题目:
计算一个整数的阶乘
如果用字母n来代表一个整数,阶乘代表着所有小于或等于n的整数的乘积。
阶乘通常简写成n!
例如:5! = 1 * 2 * 3 * 4 * 5 = 120
问题解释:
这个 function 接收一个整数为参数,返回阶乘的计算结果
比如接收的是 4,那么就返回 24
基本解法:
做一个循环,把每一步的数乘起来即可
注意,0的阶乘和1的阶乘均为1
代码:
function factorialize(num) {
var result = 1;
while (num > 1) {
result *= num;
num--;
}
return result;
}
解释:
- 循环的条件选择num>1就好,因为任何数与1相乘都不变
- 设置初始值为1,不管传入0还是1,最后得到的结果都是1,,不用进入while循环
- result *= num就相当于result = result * num
- 不写num--就会进入无限循环,此处运用for 循环也OK
思考:如果使用reduce方法
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
reducer 函数接收4个参数:
Accumulator (acc) (累计器)
Current Value (cur) (当前值)
Current Index (idx) (当前索引)
Source Array (src) (源数组)
reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
此时如果要使用reduce,首先要根据传入的num创建一个数组,显而易见,范围是1至num
也可以用Array.from创建,Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
代码:
function factorialize(num) {
return Array.from(Array(num).keys()).map(e => e + 1).reduce((prev, next) => {
return prev * next;
}, 1);
}
解释:
.keys()方法返回一个包含数组中每个索引键的Array Iterator对象。它和from都是ES6语法
.key()返回的是类数组,而且为从0开始,我们需要的是从1开始返回的数组,所以在map中加上1
再思考一下,此题可以用递归解法
function factorialize(num) {
// 初始及弹出条件
if (num === 0) {
return 1;
}
// 递归调用
return num * factorialize(num - 1)
}
上述代码的具体解释可查看翻转字符串的解释
代码中第三行条件若更改为num === 1,那么此时传入0是无法得到1的
最后,如果输入数字很大,那么就会发生栈溢出(stack overflow)的情况,FreeCodeCamp中并不要求此项,如有需要,自行搜索学习“尾递归优化”。
参考文章:S1ngS1ng:https://singsing.io/blog/fcc/basic-factorialize-a-number/