n的階乘,就是從1到n,這些數相乘的積。
如果用python來實現,有很多種方式,今天介紹3種主要方式,分別為遍歷,遞歸和內置函數。
其中遍歷分為正序遍歷和倒序遍歷,遞歸分為普通遞歸和尾遞歸,內置函數則使用reduce。
一、正序遍歷
正序遍歷,即從1依次遍歷到n,遍歷的過程中進行求積,最終得到結果。
定義一個函數positive,接收一個入參num,函數目的是打印出該數的階乘
def positive(num):
由於要進行求積操作,所以需要一個變量來存儲積,初始值為1(因為1乘以任何數都等於任何數本身)
product = 1
從1到n,每個數都要參與運算,所以需要對num進行遍歷
for i in range(num):
讓product與每一項i進行相乘,然后賦值給product
product = product * (i+1)
遍歷結束后,打印product
print(product)
代碼如下:
1 def positive(num): 2 '''正乘 :從1乘到n''' 3 product = 1 4 for i in range(num): 5 product = product * (i+1) 6 print(product) 7 8 if __name__ == '__main__': 9 num = 6 10 positive(num)
二、倒序遍歷
倒序遍歷的思路與正序基本相同,不同點是從n乘到1
依舊是定義一個方法和存儲積的變量product,初始值為1,對num進行遍歷
def positive(num):
product = 1
for i in range(num):
如果要從n乘到1,則需要讓num依次遞減,因為i是逐漸增大,所以num-i會逐漸變小,從num減到1
product = product * (num-i)
最后打印product,代碼如下:
1 def negative(num): 2 '''逆乘:從n乘到1''' 3 product = 1 4 for i in range(num): 5 product = product * (num-i) 6 print(product) 7 8 if __name__ == '__main__': 9 num = 6 10 negative(num)
三、遞歸
遞歸是方法的自調用,它的核心思想是,利用自我調用,直到滿足得到具體數值的條件后,結束遞歸自調用,返回整體運算結果。
遞歸使得代碼非常精簡,但不易理解。整體思路是,先得到n*(n-1)!,(n-1)!又可拆為(n-1)*(n-2)!,(n-2)!又可拆為(n-2)*(n-3)!
首先定義一個方法recursion,接收一個入參num
def recursion(num):
該方法要返回一個乘法運算表達式,即num * (num-1)!,(num-1)!無法直接得到,需再次調用本函數,使得每次相乘都是該數乘以該數減一的連乘積
return num * recursion(num-1)
連續階乘有了,怎么讓連續階乘結束呢,那么就需要添加一個得出具體數值的條件,即當入參num=0時,返回1
if num == 0:
return 1
這樣,當入參num=0,初次調用函數時返回的表達式就是n*(n-1)*(n-2)*...*2*1,也就是n!
代碼如下:
1 def recursion(num): 2 '''遞歸''' 3 if num == 0: 4 return 1 5 return num * recursion(num-1) 6 7 if __name__ == '__main__': 8 num = 6 9 print(recursion(num))
四、尾遞歸
尾遞歸的思想與遞歸基本相同,都是函數自調用,但區別在於遞歸返回的是數與函數之間進行的算術運算,尾遞歸是返回本函數,算術操作放在了參數中
依舊是先定義一個函數,但函數入參是2個參數,一個是要計算階乘的數num,另一個是保存每次相乘的數值,參數名假設為acc,初始值為1
def tailrecursion(num, acc=1):
函數要返回本函數的調用,將num-1和num*acc作為入參再次調用,這樣在每次調用函數時,就實現了乘積運算,且num在逐漸變小
return tailrecursion(num - 1, num * acc)
當num-1=0時,即入參的第一個參數為0,需停止自調用,返回數值acc,此時acc=num!
if num == 0:
return acc
代碼如下:
1 def tailrecursion(num,acc=1): 2 '''尾遞歸''' 3 if num == 0: 4 return acc 5 return tailrecursion(num - 1, num * acc) 6 7 if __name__ == '__main__': 8 num = 6 9 print(tailrecursion(num))
五、內置函數reduce
reduce會按照運算規則,對列表中的元素依次進行運算
所以先定義一個求積的函數,我們直接使用匿名函數,兩個入參x和y,返回x*y
lambda x, y : x * y
再定義一個從1到n的list,使用簡化方式
i+1 for i in range(num)
使用reduce函數進行組合
result = reduce( lambda x, y : x * y, (i+1 for i in range(num)) )
代碼如下:
1 if __name__ == '__main__': 2 num = 6 3 result = reduce(lambda x,y:x*y, (i+1 for i in range(num))) 4 print(result)
最終的結果都是720
