1. 程式人生 > 其它 >2000! | 看上去如此簡單的面試題,讓太多“前端”英雄好漢折戟

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迴圈增加額外的判斷條件。

更多前端開發 面試真題,請移步微信小程式 —— 決勝前端