算一算N階乘的尾隨零個數

2021-08-20 11:47:56 字數 4346 閱讀 1024

問題描述很簡單:求解n階乘的尾隨零個數

而所謂尾隨零個數,即是從個位數開始,數字連續為0的個數.

譬如:

3!(階乘符號,下同) = 3 * 2 * 1 = 6, 尾隨零個數為0

5! = 5 * 4 * 3 * 2 * 1 = 120, 尾隨零個數為1

10! = 10 * 9 * … * 1 = 3628800, 尾隨零個數為2

ok,明白問題之後,我們就來嘗試算一算吧~

方法1既然要求解階乘值的尾隨零個數,直觀的方法就是首先算出階乘值,然後對10取模來計算尾隨零個數,**如下:

function

factorial(n)

local val = 1

for i = 2, n do

val = val * i

endreturn val

endfunction

trailing_zero_count(value)

local count = 0

while

value % 10 == 0

do count = count + 1

value = value / 10

end return count

endfunction

factorial_trailing_zero_count(n)

local

value = factorial(n)

return trailing_zero_count(value)

end

方法2

方法1簡單直觀,但是當所求n階乘較大時容易造成乘法溢位(譬如n=40),一種方法是使用大數運算來解決溢位問題;另外一種更輕量的方法則是直接從尾數零的性質入手:

考慮一下,乙個數字a如果有乙個尾數零,其實就是意味著a有乙個10因子,如果有兩個尾數零,則說明a有兩個10因子(即有乙個 10 * 10 = 100 因子),以此類推~

所以我們只要知道了n階乘有多少個10因子就知道了n階乘有多少個尾數零,這裡我們不能直接計算n階乘的大小(還記的之前那個溢位問題嗎),而是要通過n階乘的定義(或者其他方式)來直接計算~

這裡我們需要一點技巧:

首先我們對10進行一下素數分解

10 = 2 * 5

n! = n * (n - 1) * (n - 2) * … * 1

假設我們能求出某個數字a中2因子的個數,求解的方法設為

factor_2_count(a)

相似的,我們設求解某個數b中5因子的個數方法為

factor_5_count(b)

那麼有:

factor_2_count(n!) = factor_2_count(n) + factor_2_count(n - 1) + factor_2_count(n - 2) + … + factor_2_count(1)

factor_5_count(n!) = factor_5_count(n) + factor_5_count(n - 1) + factor_5_count(n - 2) + … + factor_5_count(1)

又由於10 = 2 * 5(乙個2因子和乙個5因子構成乙個10因子)

所以n!的10因子個數(即尾數零個數)為:

min(factor_2_count(n!), factor_5_count(n!))(min為最小值函式)

相關**如下:

function

factor_2_count(n)

local count = 0

while n % 2 == 0

do count = count + 1

n = n / 2

end return count

endfunction

factorial_factor_2_count(n)

local count = 0

for i = 1, n do

count = count + factor_2_count(i)

endreturn count

endfunction

factor_5_count(n)

local count = 0

while n % 5 == 0

do count = count + 1

n = n / 5

end return count

endfunction

factorial_factor_5_count(n)

local count = 0

for i = 1, n do

count = count + factor_5_count(i)

endreturn count

endfunction

factorial_trailing_zero_count_v2(n)

return math.min(factorial_factor_2_count(n), factorial_factor_5_count(n))

end

方法3

考慮方法2的解法步驟,我們分別計算了n階乘中因子2的個數和因子5的個數,但實際上,n階乘中因子2的個數一定是大於等於因子5的個數的(數學歸納法應該是證明的一種方法),即:

factor_2_count(n!) >= factor_5_count(n!)

所以有:

min(factor_2_count(n!), factor_5_count(n!)) = factor_5_count(n!)

這也意味著實際上我們只需要計算n階乘中因子5的個數就可以了~

**如下:

function

factor_5_count(n)

local count = 0

while n % 5 == 0

do count = count + 1

n = n / 5

end return count

endfunction

factorial_factor_5_count(n)

local count = 0

for i = 1, n do

count = count + factor_5_count(i)

endreturn count

endfunction

factorial_trailing_zero_count_v3(n)

return factorial_factor_5_count(n)

end

方法4

方法4的理解難度相對就比較高了,考慮數n1:

n1 = n / 5

他表示的是1到n中帶有因子5的數字的個數

但根據方法3中的講述,我們需要求的是1到n中所有因子5的個數

怎麼通過n1這種計算方式來計算因子5的總數呢?

考慮數n2:

n2 = n / (5 * 5) = n / 25

他表示的是1到n中帶有因子25的數字的個數

則 n1 + n2 就代表1到n(n < 125)中所有因子5的個數,對於更大的n,我們需要繼續計算(這裡理解有些難度,不明白的同學可以多想一想~):

n3 = n / (5 * 5 * 5) = n / 125

n4 = n / (5 * 5 * 5 * 5) = n / 625

然後通過計算

n1 + n2 + n3 + n4 + …

來計算1到n中所有因子5的個數~

**如下:

function

factorial_trailing_zero_count_v4

(n) local count = 0

local factor = 5

while n >= factor do

count = count + math.

floor(n / factor)

factor = factor * 5

endreturn count

end

還有其他方法!?有知道的朋友可以告知下~

ok,我們下次再見吧~

計算n的階乘有多少個尾隨零

之前的思路是根據1 10,10個數乙個區間分析乙個區間產生多少個零,發現這個方法不靠譜,隨後閱讀資料發現以下思路 我們會發現乙個因子2和因子5組合產生乙個0,這樣我們只需統計1到n有多少個因子對,即n!的尾隨零個數,因子2的個數比因子5的個數多,因此我們只需統計出因子5的個數即可,如 統計一次5的倍...

N階乘尾部的0個數

描述 設計乙個演算法,計算出n階乘中尾部零的個數 思路 1 1 2 3 n 1 2 3 2 2 5 2 3 7 2 2 2 3 3 2 5 化成質數相乘,只有2 5才可能得到結果有尾數中有0 2 因為2的個數是比5多的,求0的個數問題就轉化成了求5的個數的問題 3 5 5 5 5 5 5有n個5 得...

一種快速求fibonacci第n個數的演算法

利用動態規則的思路,摒棄傳統的遞迴做法,可以得到一種快速的求fibonacci第n個數的演算法 求第n 從1開始 位fibonacci數 fibonacci數列前兩位為0,1.後面每一位數字等於前兩位數字之和 def fibonacci n if n 2 return n 1f 0 g 1 whil...