如无特别说明,以下题目均可用各种技术方案来解答。

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月25日): 看看下面代码,不执行写出答案,并做出解释。

1
2
3
4
$a = 1;
$b = &$a;
unset($a);
var_dump($b);

参考答案:
页面会输出 1 , 主要是引用和引用计数 ,当b =&a时 不仅仅是a和b指向同一个地址,同时还有个计数,此时计数的值是2,意味着有两个变量指向这个值 ,unset a 的时候只是切断了a 与 值之间的联系,此时并没有销毁这个地址的值

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月21日):实现下面的函数,找出对象 arguments 当中数字第二大的值,要求是call和apply都必须被合理的用到。

1
2
3
function getSecondMax() {/*code*/}

// 如调用 getSecondMax(1, 21, 13, 35, 46) 返回 35

参考答案:此题看似多此一举,重点不在这里,而是让大家了解call和apply的参数差异。

1
2
3
4
5
6
function getSecondMax(){
var arr = Array.prototype.slice.call(arguments,0);
arr.sort(function(a,b){return (a>b?-1:1)})
arr.shift()
return Math.max.apply(null, arr)
}

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月20日):一个数组相关的算法,现在有一个数组如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$items = [1,2,3,4,5,6,7,8,9]
现在要通过这个数组的数据元素重新生成长度为2,3,4...的新数组,并且统计一共组成了新数组的个数.
比如生成长度为2的数字,并且统计$b个数 例:

$b = [1,2]
$b = [1,3]
$b = [1,4]
$b = [1,5]

如果我们要实现一个函数

//$items为数组,$num为指定的长度
function mycount($items,$num){

//这里的代码等你来实现

}

参考答案:本题其实就是考如何去获取数组的子集,求子集在上半年 2014年4月9日每日一题已经给出过答案,
参考地址 :http://blog.sijiaomao.com/?p=230

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月19日):关于“JS函数的参数是否可以引用传递?”,昨天 Zjmainstay 给出了代码:

1
2
3
4
function test(user) {  user['age'] = '24';}
var my = {  name : 'Zjmainstay'}
test(my);
console.log(my);

控制台输出:{name: “Zjmainstay”, age: “24”}

看这效果,貌似就是引用传递的。那么将此代码小小修改后

1
2
3
4
function test(user) {  user = {  name : 'sijiaomao'};}
var my = {  name : 'Zjmainstay'}
test(my);
console.log(my);

如果是引用传递,控制台输出 {  name : ‘sijiaomao’} 才是符合预期的。但为何不是呢?

参考答案:

 wuhen和Zjmainstay解释都不错。这里想告诉大家的是,js当中没有引用传递。对象类型的变量,其实是一个指向该对象的指针,该指针传递给函数后,会值传递形成一个新的指针,这个指针默认也是指向该对象。所以代码1的方式会导致该对象发生变化,代码2的方式是把新指针指向了一个局部作用域的新对象,和原来的对象没有关系。

 

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月17日):在js中,如果知道一个匿名函数的名字,比方说函数名是test,那么可以直接输出这个函数体的定义代码,PHP 5.3以后也加入了匿名函数的功能,比如像这样一个函数定义:

1
2
3
$test = function () {
    echo 'hello world';
};

我能否在用类似echo $test模仿js中的方法,输出它的函数体呢?

参考答案:
以下是采用了PHP中反射的原理才读取源码中指定的代码,实现了类似js中的打印函数定义的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function closure_dump($closure) {
    try {
        $func = new ReflectionFunction($closure);
    } catch (ReflectionException $e) {
        echo $e->getMessage();
        return;
    }
    echo $func;
     $start = $func->getStartLine() - 1;

    $end =  $func->getEndLine() - 1;

  $filename = $func->getFileName();

//  echo implode("", array_slice(file($filename),$start, $end - $start + 1));
}

closure_dump($test);

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月14日):以下JavaScript代码运行的结果是什么?

1
["1","2","3"].map(parseInt)

关键是你能回答为什么吗?

以下是参考答案:

在 javascript 中 [“1″,”2″,”3″].map(parseInt) 为何返回不是 [1,2,3] 却是 [1,NaN,NaN]?

我们首先回顾一下 parseInt() 个 map() 两个函数的用法:

parseInt() 函数

定义和用法

parseInt() 函数可解析一个字符串,并返回一个整数。

语法

parseInt(string, radix)
参数 描述
string 必需。要被解析的字符串。
radix
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

如果省略该参数或其值为 ‘0‘,则数字将以 10 为基础来解析。如果它以 ‘”0x”‘ 或 ‘”0X”‘ 开头,将以 16 为基数。

如果该参数小于 2 或者大于 36,则 ‘parseInt()‘ 将返回 ‘NaN‘。

返回值

返回解析后的数字。

说明

当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。

举例:

如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。

如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。

如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

提示和注释

注释:只有字符串中的第一个数字会被返回。

注释:开头和结尾的空格是允许的。

提示:如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。

实例

在本例中,我们将使用 parseInt() 来解析不同的字符串:

parseInt(“10″); // 返回 10 (默认十进制)
parseInt(“19″,10); // 返回 19 (十进制: 10+9)
parseInt(“11″,2); // 返回 3 (二进制: 2+1)
parseInt(“17″,8); // 返回 15 (八进制: 8+7)
parseInt(“1f”,16); // 返回 31 (十六进制: 16+15)
parseInt(“010″); // 未定:返回 10 或 8
map 方法

对数组的每个元素调用定义的回调函数并返回包含结果的数组。

array1.map(callbackfn[, thisArg])
参数 定义
array1 必需。一个数组对象。
callbackfn 必需。一个接受**最多**三个参数的函数。对于数组中的每个元素,‘map‘ 方法都会调用 ‘callbackfn‘ 函数一次。
thisArg 可选。可在 ‘callbackfn‘ 函数中为其引用 ‘this‘ 关键字的对象。如果省略 ‘thisArg‘,则 ‘undefined‘ 将用作 ‘this‘ 值。
返回值

其中的每个元素均为关联的原始数组元素的回调函数返回值的新数组。

异常

如果 callbackfn 参数不是函数对象,则将引发 TypeError 异常。

备注

对于数组中的每个元素,map 方法都会调用 callbackfn 函数一次(采用升序索引顺序)。 不为数组中缺少的元素调用该回调函数。

除了数组对象之外,map 方法可由具有 length 属性且具有已按数字编制索引的属性名的任何对象使用。

回调函数语法

回调函数的语法如下所示:

function callbackfn(value, index, array1)
可使用最多三个参数来声明回调函数。

下表列出了回调函数参数。

回调参数 定义
value 数组元素的值。
index 数组元素的数字索引。
array1 包含该元素的数组对象。
修改数组对象

数组对象可由回调函数修改。

下表描述了在 map 方法启动后修改数组对象所获得的结果。

‘map‘ 方法启动后的条件 元素是否传递给回调函数
在数组的原始长度之外添加元素。 否。
添加元素以填充数组中缺少的元素。 是,如果该索引尚未传递给回调函数。
元素被更改。 是,如果该元素尚未传递给回调函数。
从数组中删除元素。 否,除非该元素已传递给回调函数。
示例

下面的示例阐释了 map 方法的用法。

// 定义回调函数
// 计算圆的面积
function AreaOfCircle(radius) {
var area = Math.PI * (radius * radius);
return area.toFixed(0);
}

// 定义一个数组,保护三个元素
var radii = [10, 20, 30];

// 计算 radii 的面积.
var areas = radii.map(AreaOfCircle);

document.write(areas);

// 输出:
// 314,1257,2827
下面的示例阐释 thisArg 参数的用法,该参数指定对其引用 this 关键字的对象。

// 定义一个对象 object,保护 divisor 属性和 remainder 方法
// remainder 函数求每个传入的值的个位数。(即除以 10 取余数)
var obj = {
divisor: 10,
remainder: function (value) {
return value % this.divisor;
}
}

// 定义一个包含 4 个元素的数组
var numbers = [6, 12, 25, 30];

// 对 numbers 数组的每个元素调用 obj 对象的 remainder 函数。
// map 函数的第 2 个参数传入 ogj。
var result = numbers.map(obj.remainder, obj);
document.write(result);

// 输出:
// 6,2,5,0
在下面的示例中,内置 JavaScript 方法用作回调函数。

// 对数组中的每个元素调用 Math.sqrt(value) (求平方根)
var numbers = [9, 16];
var result = numbers.map(Math.sqrt);

document.write(result);
// 输出: 3,4
[9,16].map(Math.sqrt) 回调函数,输出的结果是 [3,4]。 但是为什么 [“1″,”2″,”3″].map(parseInt) 却返回 [1,NaN,NaN]?

网站给出的提示是:

what you actually get is [1,NaN,NaN] because parseInt takes two parameters (val,
radix) and map passes 3 (element,
index, array)
简单翻译一下就是

parseInt 需要 2 个参数 (val,
radix), 而 map 传递了 3 个参数 (element,
index, array)」。
通过上面的解释,我们可以看出,如果想让 parseInt(string,
radix) 返回 NaN,有两种情况:

第一个参数不能转换成数字。

第二个参数不在 2 到 36 之间。

我们传入的参数都能转换成数字,所以只能是第二种可能。

到底是不是呢?我们重新定义 parseInt(string,
radix) 函数:

var parseInt = function(string, radix) {
return string + “-” + radix;
};

[“1″, “2”, “3”].map(parseInt);
输出结果为:

[“1-0″, “2-1″, “3-2″]
看见,map 函数将数组的值 value 传递给了 parseInt 的第一个参数,将数组的索引传递给了第二个参数。 第三个参数呢?我们再加一个参数

var parseInt = function(string, radix, obj) {
return string + “-” + radix + “-” + obj;
};

[“1″, “2”, “3”].map(parseInt);
输出结果:

[“1-0-1,2,3″, “2-1-1,2,3″, “3-2-1,2,3″]
我们再继续增加参数:

var parseInt = function(string, radix, obj, other) {
return string + “-” + radix + “-” + obj + “-” + other;
};

[“1″, “2”, “3”].map(parseInt);
输出结果:

[“1-0-1,2,3-undefined”, “2-1-1,2,3-undefined”, “3-2-1,2,3-undefined”]
第四个参数为 undefined,看见 map 确实为 parseInt 传递了三个参数。就像作者写道的:

(element, index, array)
数组的值

数组的索引

数组

(全文完)
本文答案转载于: http://blog.csdn.net/justjavac/article/details/19473199

Posted by & filed under 每日一题.

【四脚猫】每日一题(11月13日):通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,
将字符串中连续出现的重复字母进行压缩,并输出压缩后的字符串。 
压缩规则: 
(1) 仅压缩连续重复出现的字符。比如字符串”abcbc”由于无连续重复字符,压缩后的字符串还是”abcbc”。
(2) 压缩字段的格式为”字符+字符重复的次数”。例如:字符串”xxxyyyyyyz”压缩后就成为”x3y6z” 。
(3) 单个字符不用压缩。例如 “abc” ,压缩后还是“abc” 。

Zjmainstay的解法采用正则实现,非常的优雅!

1
2
3
4
5
6
7
8
9
10
11
12
13
//压缩
$str = preg_replace_callback('#(.)(\1+)#is', function($match){
return $match [1] . strlen($match[0]);
}, 'xxxyyyyyyz');

var_dump($str);

//解压缩
$str = preg_replace_callback('#([a-z])(\d+)#is', function($match){
return str_repeat($match [1] ,$match [2] );
}, $str);

var_dump($str);

以下是不采用正则,普通方式扫描字符串的解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
/*
此示例运行在命令行下哦 :)
*/

//压缩字符串  
function compressStr($str){
    $cstr='';
    $len=strlen($str);
    if($len<2) return $str;
    $i=1; $num=1;
    for( ; $i<$len; $i++ ){
        if( ctype_digit ($str[$i-1]) ) exit ( "Error: letter ${str[$i-1]}  is not int " );
        if($str[$i]==$str[$i-1]){
            $num++;
        }else{
            $cstr.=(1==$num)? $str[$i-1] : $str[$i-1].$num;
            $num=1 ;
        }
    }
    $cstr.=(1==$num)? $str[$i-1]  : $str[$i-1].$num;
    return $cstr;
}

//解压字符串
function unCompressStr($cstr){
    $str='';
    $len=strlen($cstr);
    for( $i=0 ; $i<$len; $i++ ){
        if( ctype_digit($cstr[$i]) ){
            $str.=str_repeat($cstr[$i-1], $cstr[$i]-1 );
        }else{
            $str.=$cstr[$i];
        }
    }
    return $str;
}

$compress=compressStr('aaabbcdeffgggaaabb');  //压缩
echo $compress.PHP_EOL;
echo unCompressStr($compress);  //解压缩