您好,登錄后才能下訂單哦!
今天小編給大家分享一下python怎么求N的階乘的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
本題要求編寫程序,計算N的階乘。
輸入格式:
輸入在一行中給出一個正整數 N。
輸出格式:
在一行中按照“product = F”的格式輸出階乘的值F,請注意等號的左右各有一個空格。題目保證計算結果不超過雙精度范圍。
輸入樣例:
5
輸出樣例:
product = 120
x = int(input()) a = 1 for i in range(1, x+1): a = a*i print("product = %d" % float(a))
問題描述:
輸入一個正整數n,輸出n!的值。
其中n!=123*…*n。
算法描述:
n!可能很大,而計算機能表示的整數范圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位,依次類推。
將a乘以一個整數k變為將數組A的每一個元素都乘以k,請注意處理相應的進位。
首先將a設為1,然后乘2,乘3,當乘到n時,即得到了n!的值。
輸入格式:
輸入包含一個正整數n,n<=1000。
輸出格式:
輸出n!的準確值。
樣例輸入:
10
樣例輸出:
3628800
看到這題我首先想到的是兩種比較簡單的解法,一是循環,二是遞歸。
n = int(input()) ns = 1 for i in range(1,n+1): ns = ns*i print(ns)
思路比較簡單,就是定義一個變量ns賦予一個初始值1,然后利用for循環直接累乘得到最終結果。
def factorial(n): if n==1: return n else: return n*factorial(n-1) n = int(input()) res = factorial(n) print(res)
遞歸也比較好理解,當n == 2,return 2 * 1;n == 3,return 3*(2 * 1);n==4,return 4*(3*(2*1))。以此類推,再將最終的結果賦予res將其打印即可。
這兩種方法都比較簡單,但很顯然都不符合題目要求的 “使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位”,所以我們要想辦法利用數組來得到n!的結果。
n= int(input()) ns = [0 for i in range(10000) ] length = 1 ns[0] = length = 1 if n>=2: for i in range(2,n+1): carry = 0 for j in range(length): temp = ns[j] * i + carry carry = int(temp/10) ns[j] = temp % 10 while carry>0: ns[length] += carry%10 length+=1 carry = int(carry/10) while length>0: length -=1 print(ns[length],end='')
接下來我講下思路:
首先定義一個ns數組用來存儲n!的各個位數上的數值,利用for循環給ns加入10000個0值,以方便后面直接根據index對數組進行操作。
然后定義length作為 “數組的長度”(有真實數值的而非自動添加的0) 也即n!的結果的位數。
之后也必須用到for循環進行累乘,但跟解法一的直接累乘不同,這里是乘數(即i)跟各個位上的數分別相乘,若結果大于等于10則carry>0即向前進一位數值為carry,若j循環結束后carry>0則說明需要在當前ns的“長度”上進一位,所以length+1即位數+1,這里carry起的就是判斷是否進位的作用,而length則代表著結果的位數。可能這么說有些抽象,下面我們通過分解運行過程來更直觀的闡述上面的想法。
例如我們現在需要求5!,分五步,即i循環5次:
ns[0] = length =1 , carry = 0 ∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =1*1+0=1 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 1/10 = 0 # carry=0所以不用進位 ns[j] = temp % 10 即 ns[0] = 1 % 10 =1 #只取個位數值作為第j位的值
ns[0] = 1, length =1 , carry = 0 ∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =1*2+0=2 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 2 / 10 = 0 # carry=0所以不用進位 ns[j] = temp % 10 即 ns[0] = 2 % 10 =2 #只取個位數值作為第j位的值 #這樣就已經的到2!的值了即2
ns[0] = 2, length =1 , carry = 0 ∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =2*3+0=6 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 6 / 10 = 0 # carry=0所以不用進位 ns[j] = temp % 10 即 ns[0] = 6 % 10 =6 #只取個位數值作為第j位的值 #這樣就已經的到3!的值了即6
ns[0] = 6, length =1 , carry = 0 ∴j in range(1)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =6*4+0=24 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 24 / 10 = 2 # carry=2>0所以需要向前進2 ns[j] = temp % 10 即 ns[0] = 24 % 10 =4 #只取個位數值作為第j位的值
j循環結束,carry>0執行while循環
while carry>0: ns[length] += carry%10 即 ns[1] += 2 % 10 = 2 #carry = 2 所以向前進2 length+=1 即 length =1+1=2 #位數加一 carry = int(carry/10) = 2 / 10 = 0 # carry = 2<10所以不需要繼續進位,while循環結束 ∴length = 2 , ns[0] = 4 ,ns[1] = 2 #這樣就得到4!的值ns[1]*10+ns[0] 即 24,輸出時可直接倒著打印然后end=''而不需要每位數乘10*n再相加
ns[0] = 4, ns[1] = 2 length =2 , carry = 0 ∴j in range(2)
⑴ j=0
temp = ns[j] * i + carry = ns[0] * i + carry =4*5+0=20 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 20 / 10 = 2 # carry=2>0所以需要向前進2 ns[j] = temp % 10 即 ns[0] = 20 % 10 =0 #只取個位數值作為第j位的值
⑵ j=1
temp = ns[j] * i + carry = ns[1] * i + carry =2*5+2=12 # temp為第j位數與i相乘并加上j-1位數與i相乘后進位的值的結果 carry = int(temp/10) = 12 / 10 = 1 # carry=1>0所以需要向前進1 ns[j] = temp % 10 即 ns[1] = 12 % 10 =2 #只取個位數值作為第j位的值
j循環結束,carry>0執行while循環
while carry>0: ns[length] += carry%10 即 ns[2] += 1 % 10 = 1 #carry = 1 所以向前進2 length+=1 即 length =2 +1 = 3 #位數加一 carry = int(carry/10) = 1 / 10 = 0 # carry = 1<10所以不需要繼續進位,while循環結束 ∴length = 3 , ns[0] = 0 , ns[1] = 2 , ns[2] = 1 # 這樣就得到5!的值ns[2] ns[1] ns[0]即 120
這樣看下來是否發現和小學的時候學的豎式乘法運算過程很相似,從低位數到高位數(ns[j],j in range(0,length))依次與乘數(i)相乘,大于十則進位(carry=temp/10>0,若ns[length]*i+carry > 10則length+1)。
以上就是“python怎么求N的階乘”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。