2013-02-03 99 views
1

我必須打印系列: -大階乘系列

n*(n-1),n*(n-1)*(n-2),n*(n-1)*(n-2)*(n-3),n*(n-1)*(n-2)*(n-3)*(n-4)...,n!. 

問題是n的值大,它可以去高達37和n!顯然會超出界限? 我只是不能開始,請幫助,如果你在我的位置,你將如何解決問題?

+0

這是從鋁齊默爾曼的編程競賽(http://www.azspcs.net/)? – WolframH

+1

你是否忘記了n *(n-1)*(n-3)*(n-4)中的(n-2)還是那個故意的? – Martinsos

+0

37!需要143位,對於大多數傳統編程語言來說太多了。您可以使用unix工具「bc」(http://www.gnu。org/software/bc /)可以處理任意精度。像C#這樣的語言有這種問題的「BigInteger」數據類型。 –

回答

3

這取決於您使用的語言。當數字對於機器的本地整數表示而言太大時,某些語言會自動切換到大整數包。在其他語言中,只需使用一個大整數庫,它應該處理37個!容易。

對於某些語言,維基百科有一個list of arbitrary-precision arithmetic libraries。網上還有很多其他資源。

+0

最好,c/C++,但你可以告訴任何語言:) 而我們不能沒有這些精度庫嗎?因爲就像在比賽中,如果我應該處理這個大計算,那麼圖書館不會來救我 - 他們是不允許的? –

+0

@AdamSmith - 我懷疑對於比賽而言,需要一種分析而不是計算方法。也就是說,訣竅是通過推理髮現一條直線程序 - 並通過推理證明它是正確的(很可能是歸納)。特別是,能夠計算37!實際上並不會幫助您找到有競爭力的SLP。但是,一般來說,處理大於原始整數類型的數字(通常最多64或128位)將需要大量的數據包。 –

+0

是的,我同意你的看法,但使用這種計算方法,我可以輕鬆得分至少10分!對於一個學校男孩來說這相當不錯:DI正在考慮首先得到我可以得到的免費積分,就像我在一般情況下有O(2(n + 1))的解決方案,並且認爲充分利用這個算法可以自由獲得積分達到然後嘗試優化與更好的方法/算法/技術:) –

0

我剛剛在Java中試過BigInteger,它的工作原理。爲便於演示

工作代碼:

import java.math.BigInteger; 

public class Factorial { 
    public static int[] primes = {2,3,5,7,11,13,17,19,23,29,31,37}; 
    public static BigInteger computeFactorial(int n) { 
     if (n==0) { 
      return new BigInteger(String.valueOf(1)); 
     } else { 
      return new BigInteger(String.valueOf(n)).multiply(computeFactorial(n-1)); 
     } 
    } 
    public static String getPowers(int n){ 
     BigInteger input = computeFactorial(n); 
     StringBuilder sb = new StringBuilder(); 
     int count = 0; 
     for (int i = 0; i < primes.length && input.intValue() != 1;) { 
      BigInteger[] result = input.divideAndRemainder(new BigInteger(String.valueOf(primes[i]))); 
      if (result[1].intValue() == 0) { 
       input = input.divide(new BigInteger(String.valueOf(primes[i]))); 
       count++; 
       if (input.intValue() == 1) {sb.append(primes[i] + "(" + count + ") ");} 
      } else { 
       if (count!=0) 
       sb.append(primes[i] + "(" + count + ") "); 
       count = 0; 
       i++; 
      } 
     } 
     return sb.toString(); 
    } 
    public static void main(String[] args) { 
     System.out.println(getPowers(37)); 
    } 
} 

隨意使用它,而不用擔心版權的,如果你想要的。

更新:我沒有意識到你到目前爲止正在使用C++。在這種情況下,您可以試一試boost BigInteger

+0

沒關係,這是我的錯,我沒有提及C++第一^ _^ 但很大的感謝特里李,投票了:) –

+0

哦對不起,我是新手,沒有投票權:) –

+0

@AdamSmith沒關係。您可以稍後投票:) –

0

您可以使用大整數,但是這仍然有一些限制,但即使此數據類型可以處理非常大的值。大整數可容納的值,範圍從
-9223372036854775808到9223372036854775807爲有符號大整數,而
0到18446744073709551615爲無符號大整數。

如果你真的打算做一些比大整數數據類型更大的值計算,爲什麼不試試GMP library

正如網站所說的那樣,「GMP是一個免費的庫,用於任意精度算術,對有符號整數,有理數和浮點數進行操作。除了可用的精度外,精度沒有實際的限制GMP運行的機器中的內存GMP具有豐富的功能,並且功能具有常規的界面。「 - gmplib.org

0

如果不允許使用任何第三方庫,則可以實現自己的大整數類型。你可以這樣做:

#include <iostream> 
    #include <iomanip> 
    #include <vector> 
    using namespace std; 

    const int base = 1000 * 1000 * 1000; // base value, should be the power of 10 
    const int lbase = 9; // lg(base) 

    void output_biginteger(vector<int>& a) { 
     cout << a.back(); 
     for (int i = (int)a.size() - 2; i >= 0; --i) 
     cout << setw(lbase) << setfill('0') << a[i]; 
     cout << endl; 
    } 

    void multiply_biginteger_by_integer(vector<int>& a, int b) { 
     int carry = 0; 
     for (int i = 0; i < (int)a.size(); ++i) { 
     long long cur = (long long)a[i] * b + carry; 
     carry = cur/base; 
     a[i] = cur % base; 
     } 
     if (carry > 0) { 
     a.push_back(carry); 
     } 
    } 

    int main() { 
     int n = 37; // input your n here 
     vector<int> current(1, n); 
     for (int i = n - 1; n >= 1; --n) { 
     multiply_biginteger_by_integer(current, i); 
     output_biginteger(current); 
     } 
     return 0; 
    } 
1

3歲的問題看起來很有趣。

簡單地創建一個例程來「乘」一個字符串因子。效率不高,但完成工作。

#include <stdlib.h> 
#include <string.h> 
void mult_array(char *x, unsigned factor) { 
    unsigned accumulator = 0; 
    size_t n = strlen(x); 
    size_t i = n; 
    while (i > 0) { 
    i--; 
    accumulator += (unsigned)(x[i]-'0')*factor; 
    x[i] = (char) (accumulator%10 + '0'); 
    accumulator /= 10; 
    } 
    while (accumulator > 0) { 
    memmove(x+1, x, ++n); 
    x[i] = (char) (accumulator%10 + '0'); 
    accumulator /= 10; 
    } 
} 

#include <stdio.h> 
void AS_Factorial(unsigned n) { 
    char buf[1000]; // Right-size buffer (problem for another day) 
    sprintf(buf, "%u", n); 
    fputs(buf, stdout); 
    while (n>1) { 
    n--; 
    mult_array(buf, n); 
    printf(",%s", buf); 
    } 
    puts(""); 
} 

樣品的使用和輸出

int main(void) { 
    AS_Factorial(5); 
    AS_Factorial(37); 
    return 0; 
} 

5,20,60,120,120 
37,1332,46620,1585080,52307640,1673844480,...,13763753091226345046315979581580902400000000 
+0

(不久之後,你將重新發布「打包的BCD算術」)。 – greybeard