大数问题(模板)

转自:http://blog.csdn.net/hackbuteer1/article/details/6595881

分别使用C++中的运算符重载的方法来实现大数之间的数学运算,包括加法、减法、乘法、除法、n次方、取模、大小比较、赋值以及输入流、输出流的重载。。

         并且使用这个大数模板,顺利AC了HDOJ上的1134这个题目的Catalan数计数问题。。http://acm.hdu.edu.cn/showproblem.php?pid=1134

大数模板的代码如下:

[cpp] 
view plain
 copy

  1. #include<iostream>   
  2. #include<string>   
  3. #include<iomanip>   
  4. #include<algorithm>   
  5. using namespace std;   
  6.   
  7. #define MAXN 9999  
  8. #define MAXSIZE 10  
  9. #define DLEN 4  
  10.   
  11. class BigNum  
  12. {   
  13. private:   
  14.     int a[500];    //可以控制大数的位数   
  15.     int len;       //大数长度  
  16. public:   
  17.     BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //构造函数  
  18.     BigNum(const int);       //将一个int类型的变量转化为大数  
  19.     BigNum(const char*);     //将一个字符串类型的变量转化为大数  
  20.     BigNum(const BigNum &);  //拷贝构造函数  
  21.     BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算  
  22.   
  23.     friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符  
  24.     friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符  
  25.   
  26.     BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算   
  27.     BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算   
  28.     BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算   
  29.     BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算  
  30.   
  31.     BigNum operator^(const int  &) const;    //大数的n次方运算  
  32.     int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算      
  33.     bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较  
  34.     bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较  
  35.   
  36.     void print();       //输出大数  
  37. };   
  38. BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数  
  39. {   
  40.     int c,d = b;  
  41.     len = 0;  
  42.     memset(a,0,sizeof(a));  
  43.     while(d > MAXN)  
  44.     {  
  45.         c = d – (d / (MAXN + 1)) * (MAXN + 1);   
  46.         d = d / (MAXN + 1);  
  47.         a[len++] = c;  
  48.     }  
  49.     a[len++] = d;  
  50. }  
  51. BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数  
  52. {  
  53.     int t,k,index,l,i;  
  54.     memset(a,0,sizeof(a));  
  55.     l=strlen(s);     
  56.     len=l/DLEN;  
  57.     if(l%DLEN)  
  58.         len++;  
  59.     index=0;  
  60.     for(i=l-1;i>=0;i-=DLEN)  
  61.     {  
  62.         t=0;  
  63.         k=i-DLEN+1;  
  64.         if(k<0)  
  65.             k=0;  
  66.         for(int j=k;j<=i;j++)  
  67.             t=t*10+s[j]-‘0’;  
  68.         a[index++]=t;  
  69.     }  
  70. }  
  71. BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数  
  72. {   
  73.     int i;   
  74.     memset(a,0,sizeof(a));   
  75.     for(i = 0 ; i < len ; i++)  
  76.         a[i] = T.a[i];   
  77. }   
  78. BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算  
  79. {  
  80.     int i;  
  81.     len = n.len;  
  82.     memset(a,0,sizeof(a));   
  83.     for(i = 0 ; i < len ; i++)   
  84.         a[i] = n.a[i];   
  85.     return *this;   
  86. }  
  87. istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符  
  88. {  
  89.     char ch[MAXSIZE*4];  
  90.     int i = -1;  
  91.     in>>ch;  
  92.     int l=strlen(ch);  
  93.     int count=0,sum=0;  
  94.     for(i=l-1;i>=0;)  
  95.     {  
  96.         sum = 0;  
  97.         int t=1;  
  98.         for(int j=0;j<4&&i>=0;j++,i–,t*=10)  
  99.         {  
  100.             sum+=(ch[i]-‘0’)*t;  
  101.         }  
  102.         b.a[count]=sum;  
  103.         count++;  
  104.     }  
  105.     b.len =count++;  
  106.     return in;  
  107.   
  108. }  
  109. ostream& operator<<(ostream& out,  BigNum& b)   //重载输出运算符  
  110. {  
  111.     int i;    
  112.     cout << b.a[b.len – 1];   
  113.     for(i = b.len – 2 ; i >= 0 ; i–)  
  114.     {   
  115.         cout.width(DLEN);   
  116.         cout.fill(‘0’);   
  117.         cout << b.a[i];   
  118.     }   
  119.     return out;  
  120. }  
  121.   
  122. BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算  
  123. {  
  124.     BigNum t(*this);  
  125.     int i,big;      //位数     
  126.     big = T.len > len ? T.len : len;   
  127.     for(i = 0 ; i < big ; i++)   
  128.     {   
  129.         t.a[i] +=T.a[i];   
  130.         if(t.a[i] > MAXN)   
  131.         {   
  132.             t.a[i + 1]++;   
  133.             t.a[i] -=MAXN+1;   
  134.         }   
  135.     }   
  136.     if(t.a[big] != 0)  
  137.         t.len = big + 1;   
  138.     else  
  139.         t.len = big;     
  140.     return t;  
  141. }  
  142. BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算   
  143. {    
  144.     int i,j,big;  
  145.     bool flag;  
  146.     BigNum t1,t2;  
  147.     if(*this>T)  
  148.     {  
  149.         t1=*this;  
  150.         t2=T;  
  151.         flag=0;  
  152.     }  
  153.     else  
  154.     {  
  155.         t1=T;  
  156.         t2=*this;  
  157.         flag=1;  
  158.     }  
  159.     big=t1.len;  
  160.     for(i = 0 ; i < big ; i++)  
  161.     {  
  162.         if(t1.a[i] < t2.a[i])  
  163.         {   
  164.             j = i + 1;   
  165.             while(t1.a[j] == 0)  
  166.                 j++;   
  167.             t1.a[j–]–;   
  168.             while(j > i)  
  169.                 t1.a[j–] += MAXN;  
  170.             t1.a[i] += MAXN + 1 – t2.a[i];   
  171.         }   
  172.         else  
  173.             t1.a[i] -= t2.a[i];  
  174.     }  
  175.     t1.len = big;  
  176.     while(t1.a[t1.len – 1] == 0 && t1.len > 1)  
  177.     {  
  178.         t1.len–;   
  179.         big–;  
  180.     }  
  181.     if(flag)  
  182.         t1.a[big-1]=0-t1.a[big-1];  
  183.     return t1;   
  184. }   
  185.   
  186. BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算   
  187. {   
  188.     BigNum ret;   
  189.     int i,j,up;   
  190.     int temp,temp1;     
  191.     for(i = 0 ; i < len ; i++)  
  192.     {   
  193.         up = 0;   
  194.         for(j = 0 ; j < T.len ; j++)  
  195.         {   
  196.             temp = a[i] * T.a[j] + ret.a[i + j] + up;   
  197.             if(temp > MAXN)  
  198.             {   
  199.                 temp1 = temp – temp / (MAXN + 1) * (MAXN + 1);   
  200.                 up = temp / (MAXN + 1);   
  201.                 ret.a[i + j] = temp1;   
  202.             }   
  203.             else  
  204.             {   
  205.                 up = 0;   
  206.                 ret.a[i + j] = temp;   
  207.             }   
  208.         }   
  209.         if(up != 0)   
  210.             ret.a[i + j] = up;   
  211.     }   
  212.     ret.len = i + j;   
  213.     while(ret.a[ret.len – 1] == 0 && ret.len > 1)  
  214.         ret.len–;   
  215.     return ret;   
  216. }   
  217. BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算  
  218. {   
  219.     BigNum ret;   
  220.     int i,down = 0;     
  221.     for(i = len – 1 ; i >= 0 ; i–)  
  222.     {   
  223.         ret.a[i] = (a[i] + down * (MAXN + 1)) / b;   
  224.         down = a[i] + down * (MAXN + 1) – ret.a[i] * b;   
  225.     }   
  226.     ret.len = len;   
  227.     while(ret.a[ret.len – 1] == 0 && ret.len > 1)  
  228.         ret.len–;   
  229.     return ret;   
  230. }  
  231. int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算      
  232. {  
  233.     int i,d=0;  
  234.     for (i = len-1; i>=0; i–)  
  235.     {  
  236.         d = ((d * (MAXN+1))% b + a[i])% b;    
  237.     }  
  238.     return d;  
  239. }  
  240. BigNum BigNum::operator^(const int & n) const    //大数的n次方运算  
  241. {  
  242.     BigNum t,ret(1);  
  243.     int i;  
  244.     if(n<0)  
  245.         exit(-1);  
  246.     if(n==0)  
  247.         return 1;  
  248.     if(n==1)  
  249.         return *this;  
  250.     int m=n;  
  251.     while(m>1)  
  252.     {  
  253.         t=*this;  
  254.         for( i=1;i<<1<=m;i<<=1)  
  255.         {  
  256.             t=t*t;  
  257.         }  
  258.         m-=i;  
  259.         ret=ret*t;  
  260.         if(m==1)  
  261.             ret=ret*(*this);  
  262.     }  
  263.     return ret;  
  264. }  
  265. bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较  
  266. {   
  267.     int ln;   
  268.     if(len > T.len)  
  269.         return true;   
  270.     else if(len == T.len)  
  271.     {   
  272.         ln = len – 1;   
  273.         while(a[ln] == T.a[ln] && ln >= 0)  
  274.             ln–;   
  275.         if(ln >= 0 && a[ln] > T.a[ln])  
  276.             return true;   
  277.         else  
  278.             return false;   
  279.     }   
  280.     else  
  281.         return false;   
  282. }  
  283. bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较  
  284. {  
  285.     BigNum b(t);  
  286.     return *this>b;  
  287. }  
  288.   
  289. void BigNum::print()    //输出大数  
  290. {   
  291.     int i;     
  292.     cout << a[len – 1];   
  293.     for(i = len – 2 ; i >= 0 ; i–)  
  294.     {   
  295.         cout.width(DLEN);   
  296.         cout.fill(‘0’);   
  297.         cout << a[i];   
  298.     }   
  299.     cout << endl;  
  300. }  
  301. int main(void)  
  302. {  
  303.     int i,n;  
  304.     BigNum x[101];      //定义大数的对象数组  
  305.     x[0]=1;  
  306.     for(i=1;i<101;i++)  
  307.         x[i]=x[i-1]*(4*i-2)/(i+1);  
  308.     while(scanf(“%d”,&n)==1 && n!=-1)  
  309.     {  
  310.         x[n].print();  
  311.     }  
  312. }  
    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/MallowFlower/article/details/78787215
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞