嗯?大数阶乘啥玩意,高中数学我已经被埋到记忆深处了,百度一下唤起模糊的记忆吧! n的阶乘:n!=n* (n-1)(n-2)...3* 2* 1。
简单,一个for循环就解决了:
n=50呢?
啊呀,有点不符合简单人类的认知啊。
n再大点呢?n=1000
直接抽象为无穷大数了,反正不知道是多少?
如何输出我们能认知的阶乘结果呢?
已字符串的形式输出我们的结果,怎样将我们的结果弄成字符串呢?
思路分析: 结果拆解存在数组中,按位求乘,去除低位,高位待相加,取完成,高位直接按位往高位进。(看不明白,反正我现在脑子是明白的)。
for exaple:
11*1024
假设结果是1024,在数组中 4201
step1: 4*11=44,低位44%10=4,放在数组当前位,高位44/10 = 4,待下一步相加
step2: 2*11 + 4= 26, 26%10 = 6,放在当前数组位,高位22/10 = 2,下次相加
step3: 0*11+2=2,2%10 =2,放在当前数组位,高位2/10 = 0,下次相加
step4: 1*11+0=11,11%10 =1,放在当前数组位,高位11/10 = 1,最后一个,1直接加入结果的高位,将数组反转过来得到结果为11264。如果高位大于10,还得循环取位。
换一种编码方式:
function factorial(n) {
if (n < 0) throw new Error('invalid input');
let result = [];
result.push(1) // 被乘数
for (let i=2; i <=n ; i++) {
// i 乘数
let mod = 0;
let length = result.length;
for (let j = 0; j < length; j++) {
let num = result[j]
let temp = num * i+mod;
mod = Math.floor(temp / 10) // 获取进位,进位可能是多位数
result[j] = temp % 10;
// 被乘数已被遍历完,将mod按位放到result中
if (j==length-1&&mod>0) {
while (mod != 0) {
result.push(mod % 10);
mod = Math.floor(mod/10);
}
}
}
}
**return** result.reverse().join('');
}
输出结果: n=10
n=50
才百万呢?
n=1000
额?这个虽然已经输出了具体数字了,但是还是超出认知了,确实是无穷大哈。
结语
这是一个题,而且还是个面试题,考察什么呢?在现实生活中有没有类似的场景呢?