世界以痛吻我,要我报之以歌
写在前面
实现这些程序,意义本身并不是很大,重要的是思考的过程。我们针对问题可能会有多种解题思路,解决方式多了,那必然就需要找出最好的,这就是算法所谓的寻找最优解。
虽然这些实现在前面的文章都已经写过了,不过我还是想简单记录下,证明我来过了,我又走了。
注:切忌眼高手低,下面直接贴代码并辅以少量说明。
阶乘
循环实现
function foo(num){
let total = 1;
while(num > 0){
total *= num;
num--;
}
return total;
}
递归实现
function foo(num){
if(num===0) return 1;
return num * foo(--num);
}
尾递归优化
懒人写法
function foo(num){
function bar(){
if(num===0) return 1;
return num * foo(--num);
}
return bar();
}
优雅的写法
function foo(num, total=1) {
if (num === 0) return total;
return foo(num - 1, num * total);
}
注: 说什么尾递归调用(TCO)只有 Safari 浏览器实现了,我特意安装了个测试,开启严格模式,那红色的 Error 啊,我心痛,我一直扪心自问,我安装的是假的...假的...的?就像那个号称无敌的双核谷歌浏览器???

蹦床函数实现
注: 通过蹦床函数实现函数柯里化,蹦床函数你可以理解为提供了一种将递归函数变为循环的通用方式,但有个前提:需要改写原来的递归函数。
function foo(num, total=1) {
if (num === 0) return total;
return foo.bind(null, num - 1, num * total);
}
function bed(fn, num){
while(fn && fn instanceof Function){
fn = fn();
}
return fn;
}
// 使用
var a = bed(foo(4));
斐波那契数列
循环实现
function Fib(num){
let [first, second, res] = [1, 1, 1];
while(num > 2){
res = first + second;
first = second;
second = res;
num--;
}
return res;
}
递归实现
function Fib(num){
let res = 1;
if(num > 2) return Fib(num-1) + Fib(num-2);
return res;
}
迭代器实现
var Fib = {
[Symbol.iterator](){
let [first, second] = [0, 1];
return {
[Symbol.iterator](){
return this;
},
next(){
let temp = second;
second = first + second;
first = temp;
return {
value: temp,
done: false
}
},
return(val){
console.log(`结束了`);
return {
value: val,
done: true
}
}
}
}
}
// 使用
for(let item of Fib){
if(item > 50) break;
console.log(item);
}
生成器实现
function *Fib(){
let [first, second] = [0, 1];
while(true){
let temp = second;
second = first + second;
first = temp;
yield temp;
}
}
// 使用
for(let item of Fib()){
if(item > 50) break;
console.log(item);
}