2000! | 看上去如此簡單的面試題,讓太多“前端”英雄好漢折戟
HTML5學堂-碼匠:求某個數字的階乘,很難嗎?看上去這道題異常簡單,卻不曾想裡面暗藏殺機,讓不少前端面試的英雄好漢折戟沉沙。
面試真題題目
如何求“大數”的階乘(如1000的階乘、2000的階乘)
或許這是你的第一反應
You
So easy!正常一個一個乘出來不就好了?
碼匠好友
for迴圈即可,再高大上點,用個遞迴不就搞定了?
或許這是你的第二反應
You
等等!大公司面試題會這麼簡單?
碼匠好友
如果我沒記錯……JS有位數限制
You
不是有科學計數法麼……
什麼是階乘
一個正整數的階乘(英語:factorial)是所有小於及等於該數的正整數的積,並且0的階乘為1。
5的階乘 5! 等價於
5*4*3*2*1
Number數字的數值範圍
在大多數瀏覽器當中:
● 最小數字是5e-324;(可以理解為浮點後324位)
● 最大數字是1.7976931348623157e+308;(可以理解為309位)
對於超過此範圍的數字,會顯示為Infinity或 -Infinity(正無窮、負無窮)。
遞迴實現階乘
function fact(maxNum) { if (maxNum > 1) { return maxNum * fact(maxNum - 1); } else { return 1; } } var result = fact(170); console.log(result);
執行結果:
7.257415615307994e+306
對於170!以下的階乘,是可以使用遞迴實現的,對於大於170的數字,階乘數已超出範圍,會顯示為Infinity。
大數階乘如何實現
實現思路
將一個數字的每一位(個位、十位、百位、千位……)拆分出來,構成一個數組。
每次計算時,針對每一位進行數學運算,並遵循逢十進一的原則,修改陣列中每一個數組元素的內容。
在完成所有運算之後,可以通過陣列的join方法,將每一位連線起來,組成“字串”輸出~
核心功能函式
var result = [1]; var maxNum = 300; for (var num = 2; num <= maxNum; num++) { for (var i = 0, plus = 0; i < result.length || plus != 0; i++) { var count = (i < result.length) ? (num * result[i] + plus) : plus; result[i] = count % 10; plus = (count - result[i]) / 10; }; }; console.log(result.reverse().join(""));
300! 的運算結果
部分程式碼說明
將當前被乘數拆分為陣列,每位的位數分別進行乘法運算。
當count大於10時,進位,再讓下一位數字與之計算。此時,需要有一個變數(plus)儲存前一位得到的餘數。
對於位數發生變化時(如結果從兩位數在計算之後變化為三位數),當前的result長度不能滿足,所以需要為for迴圈增加額外的判斷條件。
更多前端開發 面試真題,請移步微信小程式 —— 決勝前端