JavaScript阶乘末尾零计数函数上限问题及优化实现方案求助
优化方案:用数学技巧直接统计末尾零
其实末尾的零只来自阶乘中因数2和5的配对,而在n!里,因数2的数量永远比5多,所以我们只需要统计n!中包含多少个因数5就行。公式很简单:
末尾零的个数 = floor(n/5) + floor(n/25) + floor(n/125) + floor(n/625) + ... 直到除数大于n
比如:
- 100! 里,floor(100/5)=20,floor(100/25)=4,floor(100/125)=0,总和是24,所以末尾有24个零。
对应的JavaScript代码:
function countTrailingZeros(n) { let zeroCount = 0; let divisor = 5; while (divisor <= n) { zeroCount += Math.floor(n / divisor); divisor *= 5; } return zeroCount; } // 测试示例 console.log(countTrailingZeros(21)); // 输出4,正确 console.log(countTrailingZeros(10000)); // 输出2499,完全没问题
如果需要计算超大数阶乘(比如10000!)
如果你的需求不只是统计零,还需要得到完整的阶乘结果,那得用大整数模拟乘法(用数组或字符串存储每一位数字),避免Number的精度限制。代码示例:
function bigFactorial(n) { // 用数组存储数字,低位在前(方便进位处理) let digits = [1]; for (let i = 2; i <= n; i++) { let carry = 0; // 逐位相乘并处理进位 for (let j = 0; j < digits.length; j++) { const product = digits[j] * i + carry; digits[j] = product % 10; carry = Math.floor(product / 10); } // 处理剩余的进位 while (carry > 0) { digits.push(carry % 10); carry = Math.floor(carry / 10); } } // 反转数组得到正确的数字顺序 return digits.reverse().join(''); } // 测试 console.log(bigFactorial(22)); // 输出1124000727777607680000,精确无误 console.log(bigFactorial(10000).length); // 输出35660,正确的位数
如果要结合统计零,直接从大整数结果的末尾数零就行,不过还是推荐用前面的数学方法,效率高得多。
内容的提问来源于stack exchange,提问作者bmchaitu
相关产品推荐
相关产品推荐

