用c ++中的字符串表示大数字的阶乘

时间:2013-06-29 22:02:03

标签: c++ string integer factorial

我正在使用字符串进行因子程序,因为我需要数字因子大于250

我打算用:

string factorial(int n){
    string fact="1";
    for(int i=2; i<=n; i++){
        b=atoi(fact)*n;

    }

}

但问题是atoi不起作用。如何将我的字符串转换为整数。

而且最重要的是我想知道这种方式的程序是否适用于例如400的阶乘?

9 个答案:

答案 0 :(得分:3)

有一个网站可以为您计算因子:http://www.nitrxgen.net/factorialcalc.php。它报道:

  

得到的阶乘250!是493位长。   结果还包含62个尾随零(占整数的12.58%)

     

323285626090910773232081455202436847099484371767378066674794242711282374755511120948881791537102819945092850735318943292673093171280899082279103027907128192167652724018926473321804118626100683292536513367893908956993571353017504051317876007724793306540​​2339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000

许多使用C ++ double的系统最多只能工作1E + 308或其左右;价值250!太大了,无法存储在这样的数字中。

因此,您需要使用某种多精度算术库,您可以使用C ++ string值设计自己的算法,也可以使用其他一些广泛使用的多精度库(GNU {例如{3}}。

答案 1 :(得分:1)

以下代码使用unsigned double long来计算非常大的数字。

#include<iostream.h>


int main()
{
    long k=1;
    while(k!=0)
    {
        cout<<"\nLarge Factorial Calculator\n\n";
        cout<<"Enter a number be calculated:";

        cin>>k;

        if (k<=33)
        {
            unsigned double long fact=1;
            fact=1;
            for(int b=k;b>=1;b--)
            {
                    fact=fact*b;
            }
            cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
        }


        else
        {
            int numArr[10000];
            int total,rem=0,count;       
            register int i;              
            //int i;
            for(i=0;i<10000;i++)
            numArr[i]=0;             

            numArr[10000]=1;  
            for(count=2;count<=k;count++)   
            {
            while(i>0)
            {
                total=numArr[i]*count+rem;  
                rem=0;
                if(total>9)
                {
                    numArr[i]=total%10;
                    rem=total/10;
                }
                else
                {
                    numArr[i]=total;    
                }
                i--;             
            }
                rem=0;
                total=0;
                i=10000;
            }
            cout<<"The factorial of "<<k<<" is \n\n";
            for(i=0;i<10000;i++)            
                {
                    if(numArr[i]!=0 || count==1)  
                    {
                    cout<<numArr[i];
                    count=1;
                }
            }
            cout<<endl;
        }

        cout<<"\n\n";
    }//while
return 0;

}

输出:

![Large Factorial Calculator

Enter a number be calculated:250
The factorial of 250 is

32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]

答案 2 :(得分:1)

不确定为什么要尝试使用字符串。可能是通过不使用整数向量来节省一些空间?这是我的解决方案,通过使用整数向量来存储factorial和print.Works以及400或任何大数字的问题!

//Factorial of a big number

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



int main(){
    int num;
    cout<<"Enter the number :";
    cin>>num;
    vector<int> res;
    res.push_back(1);
    int carry=0;
    for(int i=2;i<=num;i++){
        for(int j=0;j<res.size();j++){
            int tmp=res[j]*i;
            res[j]=(tmp+carry)%10 ;
            carry=(tmp+carry)/10;

        }
        while(carry!=0){
            res.push_back(carry%10);
            carry=carry/10;
        }

    }

    for(int i=res.size()-1;i>=0;i--) cout<<res[i];
    cout<<endl;





    return 0;
}

输入数字:400 的400阶乘:64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

答案 3 :(得分:0)

你可以通过添加c_str()来进行atoi编译,但是在获得阶乘之前还有很长的路要走。目前你没有b。如果你有,你仍然用int乘以int。因此,即使您最终在返回之前将其转换为字符串,您的范围仍然有限。在你开始实际使用ASCII进行乘法或使用bignum库之前,没有必要使用字符串。

答案 4 :(得分:0)

逻辑应该是:

unsigned int factorial(int n)
{
    unsigned int b=1;
    for(int i=2; i<=n; i++){
        b=b*n;
    }
    return b;
}

但是b可能会溢出。所以你可以使用更大的整数类型。 或者你可以使用不准确但可以容纳更多数字的浮点类型。 但似乎没有一种内置类型足够大。

答案 5 :(得分:0)

你的因子依赖于转换为int,它会快速溢出,所以你希望能够以这种方式计算大因子。要正确地实现对大数字的计算,你需要实现逻辑,就像在纸上计算一样,你在小学就读过的规则,但把长长的整数视为“原子”,而不是单个数字。并且不要在字符串上执行它,它会非常缓慢且充满讨厌的转换

答案 6 :(得分:0)

如果要为大于12的数字求解阶乘,则需要采用与使用atoi不同的方法,因为这只会给出一个32位整数,无论​​你做什么,你都是不会超过20亿(给予或接受)。即使你的数字加倍,你也只能达到20或21左右。

编写一个字符串乘法例程并不是那么难(相对而言),它采用一个小的(ish)数字并乘以每个数字并将结果涟漪到数字(从数字的后面开始,然后填充它)向上)。

这是我的混淆代码 - 它是故意编写的,你不能把它当作学校的家庭作业,但它似乎有用(与Jonathan Leffler的回答中的数字相符),并且至少可以工作(至少)20000! [有足够的记忆]。

std::string operator*(const std::string &s, int x)
{
    int l = (int)s.length();
    std::string r;
    r.resize(l);
    std::fill(r.begin(), r.end(), '0');
    int b = 0;
    int e = ~b;
    const int c = 10;
    for(int i = l+e; i != e;)
    {
        int d = (s[i]-0x30) * x, p = i + b;
        while (d && p > e)
        {
            int t  = r[p] - 0x30 + (d % c);
            r[p] = (t % c) + 0x30;
            d = t / c + d / c;
            p--;
        }
        while (d)
        {
            r = static_cast<char>((d % c) +0x30)+r;
            d /= c;
            b++;
        }
        i--;
    }
    return r;
}

答案 7 :(得分:0)

在C ++中,最大的整数类型是'long long',它拥有64位内存,所以显然你不能存储250!整数类型。使用字符串是一个聪明的主意,但你基本上用你的代码做的是(我从未使用过atoi()函数,所以我不知道它是否适用于大于1个字符的字符串,但它不是没关系):

  1. 将字符串转换为整数(如果此代码运行良好,则在一瞬间包含249的值!)
  2. 乘以字符串的值
  3. 因此,在完成乘法后,您甚至不会将整数转换回字符串。即使你这样做,在你将字符串转换回整数的某个时刻,程序也会崩溃,因为整数将无法保存字符串的值。

    我的建议是,将一些类用于大整数。不幸的是,C ++中没有一个可用,因此您必须自己编写代码或在Internet上找到一个代码。但是,不要担心,即使你自己编码,如果你想一点,你会发现它并不那么难。你甚至可以将你的想法与字符串结合使用,对于这个问题,即使对于这个问题来说,这也不是最好的方法,但仍然会在不使用太多内存的情况下在所需的时间内产生结果。

答案 8 :(得分:0)

这是一个典型的高精度问题。

您可以使用unsigned long long数组代替字符串。 像这样:

           // $estimate='PT1H30M15S';
           // $estimate='146.76';
           // $estimate='146,76';
            $estimate=146.76;
            $json = array(
                'name' => $Project['client_order_ref'],
                "clientId" => $client[0]->id,
                "isPublic" => "false",
                "estimate" => array(
                    "estimate" => $estimate,
                    "type" => "MANUAL"
                ),
                "color" => "#f44336",
                "billable" => "true",

            );

它应该比字符串快。

但是除非紧急,您仍然可以使用字符串。

要计算10000,可能需要几天的时间。

我喜欢使用字符串,因为它易于编写。

struct node
{
    unsigned long long digit[100000];
}