今天下午群里发布的任务是使用js计算10000以内的回文数,我借鉴了以前练习过的c++的算法写了一个。
function ispalindrome(i) {
var m, n;
var palindrome = false;
m = i;
n = 0;
while (m > 0) {
n = (n * 10) + (m % 10);
m = parseInt(m / 10);
//m = ~~(m/10) 更推荐使用 ~~
//好像 ~~ 比 parseInt() 更加规范,也更加迅速。
//parseInt可以用来取整,但是parseInt本身是字符串方法,
//在转换非常小的数时由于计数采用科学记数法所以转换时会报错
//详解见下文的引用
}
if (i === n) {
palindrome = true;
}
return palindrome;
}
var palindromeArr = [];
for (var i = 1; i < 10000; i++) {
if (ispalindrome(i)) {
palindromeArr.push(i);
}
}
console.log(palindromeArr);
运行结果如下:
另外群里的其他人也给出了其他的解法,一并将代码贴上来好了。
解法一:
function getReverseNumber(num) {
var result = [];
for(var i = 10; i < num + 1; i++) {
var a = i.toString();
var b = a.split("").reverse().join("");
if(a === b) { result.push(b); }
};
return result;
}
var result=getReverseNumber(10000);
console.log(result);
解法二:
let ret = Array.from(new Array(10000), (v,i) => (i+1)).filter(v => {
let nv = v.toString().split('').reverse().join('')
return nv == v && v > 10
})
console.log(ret)
顺便在chrome中跑了一下千万级别三种算法的运算时间:
运算时间比较
运算时间大致比例为1:7:10,浮点运算相对于字符串运算还是比较快的。
至于深层次的性能剖析,目前自己还做不到(大学算法分析学的跟渣渣一样!=_="),看来抽空得弥补一下这一块的空白了。
以下解释出自 https://github.com/justjavac/the-front-end-knowledge-you-may-dont-know/issues/4
感谢 justjavac 提供的解释
parseInt
并不是取整。看函数签名:
parseInt(string, radix);
parseInt()
函数解析一个字符串参数,并返回一个指定基数的整数 (数学系统的基础)。
对比
parseInt
和 ~~
:
非常小的数:
> ~~0.0000000003
0
> parseInt(0.0000000003)
3
> Math.floor(0.0000000003)
0
因为 0.0000000003
会使用科学计数法表示为 3e-10
,parseInt
会首先把参数转换为字符串,然后解析整数,直到遇到不是数字的值。
> parseInt('2017-07-04')
2017
非常大的数
位运算的所有数都是 Int32 类型。
非规格浮点数
parseInt
解析字符串 '-0'
会得到 -0
。如果参数是数字 -0
,会得到 0
。
结论
一般情况,不建议使用位运算,因为
- 对性能提升不是很大
- 可读性差
特殊情况,如果你的返回值是整数(int32),那么可以使用位运算。使用位运算就不需要再去考虑那些非常规的值 NaN
、undefined
、null
等,这些值都是 0
。0
也只有唯一的值,不存在 +0
和 -0
。
网友评论