大数阶乘输出

223 阅读2分钟

嗯?大数阶乘啥玩意,高中数学我已经被埋到记忆深处了,百度一下唤起模糊的记忆吧! n的阶乘:n!=n* (n-1)(n-2)...3* 2* 1。

简单,一个for循环就解决了:

image.png

n=50呢?

image.png

啊呀,有点不符合简单人类的认知啊。

n再大点呢?n=1000

image.png

直接抽象为无穷大数了,反正不知道是多少?

如何输出我们能认知的阶乘结果呢?

已字符串的形式输出我们的结果,怎样将我们的结果弄成字符串呢?

思路分析: 结果拆解存在数组中,按位求乘,去除低位,高位待相加,取完成,高位直接按位往高位进。(看不明白,反正我现在脑子是明白的)。

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

image.png

n=50

image.png 才百万呢?

n=1000

image.png 额?这个虽然已经输出了具体数字了,但是还是超出认知了,确实是无穷大哈。

结语

这是一个题,而且还是个面试题,考察什么呢?在现实生活中有没有类似的场景呢?

参考

zhuanlan.zhihu.com/p/107038117 【半颗糖豆】