c语言 n阶阶乘尾0个数,算一算N阶乘的尾随零个数

问题描述很简单: 求解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

end

return val

end

function trailing_zero_count(value)

local count = 0

while value % 10 == 0 do

count = count + 1

value = value / 10

end

return count

end

function 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

end

function factorial_factor_2_count(n)

local count = 0

for i = 1, n do

count = count + factor_2_count(i)

end

return count

end

function factor_5_count(n)

local count = 0

while n % 5 == 0 do

count = count + 1

n = n / 5

end

return count

end

function factorial_factor_5_count(n)

local count = 0

for i = 1, n do

count = count + factor_5_count(i)

end

return count

end

function 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

end

function factorial_factor_5_count(n)

local count = 0

for i = 1, n do

count = count + factor_5_count(i)

end

return count

end

function 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

end

return count

end

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

OK,我们下次再见吧~

本文同步分享在 博客“tkokof1”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值