2017-05-07 63 views
3

我寫了這個函數返回給定數Swift 3計算析因數。結果變得太高?

func factorial(_ n: Int) -> Int { 
    if n == 0 { 
     return 1 
    } 
    else { 
     return n * factorial(n - 1) 
    } 
} 

print(factorial(20)) // 2432902008176640000 

作品,因爲它應該的階乘,只要給定數量不超過20個,因爲那麼結果過高?

我怎樣才能繞過這個限制,從而計算更高數字的階乘?

已經找遍了,發現了Swift的一些bignum庫,我正在學習這些知識並且熟悉Swift,因此我想自己想一想。

+0

整數具有2^64的限制。如果你想要比那更大,那麼你將不得不使用字符串或組合更小的整數等等......然後你需要計算出如何添加/除法/乘/減等等...... – Fogmeister

+0

[BigInteger相當於在Swift中?](http://stackoverflow.com/q/25531914/2227743) – Moritz

回答

5

這裏有一個方法,可以讓你找到非常大的因子。

將大數字表示爲數組數組。例如987將是[9, 8, 7]。將該數字乘以整數n將需要兩個步驟。

  1. 將該數組中的每個值乘以n
  2. 執行進位操作以返回單個數字的結果。

例如987 * 2

let arr = [9, 8, 7] 
let arr2 = arr.map { $0 * 2 } 
print(arr2) // [18, 16, 14] 

現在,執行進位操作。從個位數開始,14太大,因此請保留4並攜帶1。將1加到16得到17

[18, 17, 4] 

重複與十位:

[19, 7, 4] 

然後用百位:

[1, 9, 7, 4] 

最後,打印,你可以將此轉換回字符串:

let arr = [1, 9, 7, 4] 
print(arr.map({String($0)}).joined()) 

1974年


應用該技術,這裏是一個carryAll功能進行套利操作,並使用它來計算非常大的階乘一個factorial

func carryAll(_ arr: [Int]) -> [Int] { 
    var result = [Int]() 

    var carry = 0 
    for val in arr.reversed() { 
     let total = val + carry 
     let digit = total % 10 
     carry = total/10 
     result.append(digit) 
    } 

    while carry > 0 { 
     let digit = carry % 10 
     carry = carry/10 
     result.append(digit) 
    } 

    return result.reversed() 
} 



func factorial(_ n: Int) -> String { 
    var result = [1] 
    for i in 2...n { 
     result = result.map { $0 * i } 
     result = carryAll(result) 
    } 

    return result.map({String($0)}).joined() 
} 

print(factorial(1000)) 

402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120 8749754624970436014182780946464962910563938874378864873371191810458257836478499770124766328898359557354325131853239584630755574091142624174743493475534286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713483120254785893207671691324484262361314125087802080002616831510273418279777047846358681701643650241536913982812648102130927612448963599287051149649754199093422215668325720808213331861168115536​​158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021394503997362807501378376153071277619268490343526252000158885351473316117021039681759215109077880193931781141945452572238655414610628921879602238389714760885062768629671466746975629112340824392081601537808898939645182632436716167621791689097799119037540312746222899880051954444142820121873617459926429565817466283029555702990243241531816172104658320367869061172601587 8352075151628422554026517048330422614397428693306169089796848259012545832716822645806652676995865268227280707578139185817888965220816434834482599326604336766017699961283186078838615027946595513115655203609398818061213855860030143569452722420634463179746059468257310379008402443243846565724501440282188525247093519062092902313649327349756551395872055965422874977401141334696271542284586237738753823048386568897646192738381490014076731044664025989949022222176590433990188601856652648506179970235619389701786004081188972991831102117122984590164192106888438712185564612496079872290851929681937238864261483965738229112312502418664935314397013742853192664987533721894069428143411852015801412334482801505139969429015348307764456909907315243327828826986460278986432113908350621709500259738986355427719674282224875758676575234422020757363056949882508796892816275384886339690995982628095612145099487170124451646126037902930912088908694202851064018215439945715680594187274899809425474217358240106367740459574178 5160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

+0

好的和相輔相成的答案,非常感謝你 – Jon

0

你可以使用這個庫: BigInt

安裝它使用的CocoaPods:

pod 'BigInt' 

然後你可以使用它像這樣:

import BigInt 

    func factorial(_ n: Int) -> BigInt { 
     if n == 0 { 
      return 1 
     } 
     else { 
      return BigInt(n) * factorial(n - 1) 
     } 
    } 

    print(factorial(50)) // 30414093201713378043612608166064768844377641568960512000000000000