求一个任意数的阶乘
方法一:
def fac(n):
result = 1
for i in range(2, n+1):
result *= i # 等效于 result = result * i
return result
if __name__ == '__main__':
num = 10 # 设置任何数,计算阶层
for n in range(1, num+1):
print('{}! = {}'.format(n, fac(n)))
输出:
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
以上方法在Python中是可以的,但是如果是在 C 或者 Java 中就会导致内存溢出,比方说100的阶乘。
方法二:
思路解释:方法二就是利用了列竖式的原理,其中的add就相当于是这里的进位,a就相当于这里的乘数16,算阶乘时,从1乘到N,会发现1x2x3这几步都是个位数,所以后面的while循环用不到,因为没有进位,所以此时result列表都是一个元素在被更改而已,x3的时候元素为6,等到乘以4的时候n = 6x4+0=24,result列表的元素先被更新为4,然后因为add为2,又在列表中追加一个元素2,此时列表为[4, 2],所以会发现result列表里的元素,始终是计算结果的倒序。这也就说明从左往右按照索引取列表中的元素和a相乘和我们列竖式从个位往左取数和a相乘其实是一样的,只需要把结果倒序一下就可以了,这也就是为什么要用reversed原因了。
而这种方式的好处在于,可以确保运算过程中每次和a相乘的数都是一位数,且最终的结果也是字符串的形式,这样即使在C或者Java中也不会造成内存溢出的问题。
def fac(n):
result = [1]
for a in range(2, n+1):
mul(result, a)
return to_string(result)
""" 这里mul,to_string函数可以放在fac2下面定义,整个程序在运行的时候,
是先保存了函数的定义,再去运行主程序调用函数 """
def mul(result, a):
add = 0
for i in range(len(result)): # 遍历列表的索引
n = result[i] * a + add
result[i] = n % 10
add = n // 10
while add > 0:
result.append(add)
add //= 10 # 等效于 add = add // 10
def to_string(result):
return ''.join([str(e) for e in reversed(result)])
if __name__ == '__main__':
num = 10
for n in range(1, num+1):
print('{}! = {}'.format(n, fac(n)))
输出:
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800