大数模板

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<conio.h>
  4 #include<stdlib.h>
  5 #include<time.h>
  6 #define N 1000
  7 // 大数模板。。。
  8 class BigNum
  9 {
 10   public:
 11     int s[N];  //存放各位数字,s[0]为符号位,1代表正数,-1代表负数
 12                //数组内高位存高位,123存在里面则为 1 3 2 1 ,第1个 1表示符号
 13     int len;   //长度
 14   public:
 15     BigNum()
 16     {
 17       memset(s,0,sizeof(s));  //初始化全0
 18       s[0]=1;                 //默认正数
 19       len=2;                  //变量初始化为0
 20     }
 21     int in()              //输入
 22     {
 23       char tmp[N];
 24       int flag=scanf("%s",tmp);
 25       *this=tmp;
 26       return flag;
 27     }
 28     void out()            //输出
 29     {
 30       if(s[0]==-1) printf("-");
 31       for(int i=len-1;i>0;i--)
 32         printf("%d",s[i]);
 33     }
 34     void Clear()
 35     {
 36       memset(s,0,sizeof(s));  //初始化全0
 37       s[0]=1;                 //默认正数
 38       len=2;                  //变量初始化为0
 39     }
 40     BigNum Nizhi()            //排除符号位颠倒数组
 41     {
 42       BigNum ans;
 43       ans.s[0]=s[0];
 44       for(int i=1;i<=len/2;i++)
 45       {
 46         ans.s[i]=s[len-i];
 47         ans.s[len-i]=s[i];
 48       }
 49       ans.len=len;
 50       return ans;
 51     }
 52     friend bool operator<(const BigNum &a,const BigNum &b);
 53     friend bool operator>(const BigNum &a,const BigNum &b);
 54     friend bool operator<=(const BigNum &a,const BigNum &b);
 55     friend bool operator>=(const BigNum &a,const BigNum &b);
 56     friend BigNum operator+(BigNum a,BigNum b);
 57     friend void operator+=(BigNum &a,BigNum b);
 58     friend BigNum operator-(BigNum a,BigNum b);
 59     friend void operator-=(BigNum &a,BigNum b);
 60     friend BigNum operator*(BigNum a,BigNum b);
 61     friend void operator*=(BigNum &a,BigNum b);
 62     friend BigNum operator/(BigNum a,BigNum b);
 63     friend void operator/=(BigNum &a,BigNum b);
 64     friend BigNum operator%(BigNum &a,BigNum b);
 65     friend void operator%=(BigNum &a,BigNum b);
 66     friend bool operator==(const BigNum &a,const BigNum &b);
 67     void operator=(const int a);
 68     void operator=(const char *a);
 69     BigNum operator--();
 70     BigNum operator--(int);
 71     BigNum operator++();
 72     BigNum operator++(int);
 73 };
 74 bool operator<(const BigNum &a,const BigNum &b)
 75 {
 76   bool flag;
 77   if(a.s[0]==-1&&b.s[0]==1) return 1;      //如果a为负,b为正,那么a<b
 78   else if(a.s[0]==1&&b.s[0]==-1) return 0; //如果a为正,b为负,那么a>b
 79   else if(a.s[0]==1&&b.s[0]==1) flag=1;    //如果a、b都为正,flag=1,表示a、b大小和符号无关
 80   else flag=0;                             //如果a、b都为负,flag=0,表示a、b大小和符号有关
 81   // flag=1 时,a、b大小和除符号外的数字大小成正比,反之反比
 82   if(a.len>b.len) return !flag; //a的位数多,所以a大,返回0
 83   else if(a.len<b.len) return flag; //a的位数少,所以a小,返回1
 84   else
 85   {
 86     int i=a.len;                    //从最高位开始比
 87     while(i-->1)
 88     {
 89       if(a.s[i]>b.s[i]) return !flag;
 90       else if(a.s[i]<b.s[i]) return flag;
 91     }
 92     return 0;                       //没有差异即相等返回0
 93   }
 94 }
 95 bool operator<=(const BigNum &a,const BigNum &b) //同 <
 96 {
 97   bool flag; // flag=1 表示两者都是正的 =0表示两者都是负的
 98   if(a.s[0]==-1&&b.s[0]==1) return 1;
 99   else if(a.s[0]==1&&b.s[0]==-1) return 0;
100   else if(a.s[0]==1&&b.s[0]==1) flag=1;
101   else flag=0;
102   // flag 表示1 ,!flag 表示0
103   if(a.len>b.len) return !flag;
104   else if(a.len<b.len) return flag;
105   else
106   {
107     int i=a.len;
108     while(i-->1)
109     {
110       if(a.s[i]>b.s[i]) return !flag;
111       else if(a.s[i]<b.s[i]) return flag;
112     }
113     return 1;
114   }
115 }
116 bool operator>(const BigNum &a,const BigNum &b)
117 {
118   return !(a<=b);
119 }
120 bool operator>=(const BigNum &a,const BigNum &b)
121 {
122   return !(a<b);
123 }
124 bool operator==(const BigNum &a,const BigNum &b)
125 {
126   if(a.s[0]==-1&&b.s[0]==1) return 0;
127   else if(a.s[0]==1&&b.s[0]==-1) return 0;
128   if(a.len>b.len) return 0;
129   else if(a.len<b.len) return 0;
130   else
131   {
132     int i=a.len;
133     while(i-->1)
134     {
135       if(a.s[i]>b.s[i]) return 0;
136       else if(a.s[i]<b.s[i]) return 0;
137     }
138     return 1;
139   }
140 }
141 BigNum operator-(BigNum a,BigNum b)
142 {
143   BigNum ans;
144   if(a.s[0]==1&&b.s[0]==-1)      //如果a正,b负,那么等同于a+|b|
145   {
146     b.s[0]=1;
147     return a+b;
148   }
149   else if(a.s[0]==-1&&b.s[0]==1) //如果a负,b正,那么等同于-(|a|+b)
150   {
151     a.s[0]=1;
152     ans=a+b;
153     ans.s[0]=-1;
154     return ans;
155   }
156   else if(a.s[0]==-1&&b.s[0]==-1) //如果a负,b负,那么等同于|b|-|a|
157   {
158     a.s[0]=1;
159     b.s[0]=1;
160     return b-a;
161   }
162   else             //进到这一区域的,a为正,b为正
163   {
164     if(a<b)        //如果a<b,那么等同于-(b-a)
165     {
166       ans=b-a;
167       ans.s[0]=-1;
168     }
169     else           //进到这一区域a、b为正,且a>b,也就是说减出来的绝对是正数
170     {
171       int i=0;
172       int lm=a.len>b.len?a.len:b.len;  //由于减出来必定是正数,不需要考虑lm-1位<0的情况
173       for(int i=1;i<lm;i++)
174       {
175         int tmp=ans.s[i]+a.s[i]-b.s[i];
176         if(tmp<0)
177         {
178           ans.s[i+1]--;
179           tmp+=10;
180         }
181         ans.s[i]=tmp;
182       }
183       while(lm>2)    //清楚高位0,最多清楚到0为止
184       {
185         if(ans.s[lm-1]==0) lm--;
186         else break;
187       }
188       ans.len=lm;
189     }
190   }
191   return ans;
192 }
193 void operator-=(BigNum &a,BigNum b)
194 {
195   a=a-b;
196 }
197 BigNum operator+(BigNum a,BigNum b)
198 {
199   BigNum ans;
200   int lm=a.len>b.len?a.len:b.len;
201   if(a.s[0]*b.s[0]==1)   //如果两者符号位相同
202   {
203     ans.s[0]=a.s[0];     //结果符号位与任意一个相同
204     for(int i=1;i<lm;i++)
205     {
206       int tmp=ans.s[i]+a.s[i]+b.s[i];
207       if(tmp>=10)
208       {
209         ans.s[i+1]++;
210       }
211       ans.s[i]=tmp%10;
212     }
213     if(ans.s[lm]==0) ans.len=lm; //如果最高位没有进位,那么长度不变,否则加1
214     else ans.len=lm+1;
215   }
216   else                           //如果a、b符号不同,可以转化为减法
217   {
218     if(a.s[0]==1)
219     {
220       b.s[0]=1;
221       return a-b;
222     }
223     else
224     {
225       a.s[0]=1;
226       return b-a;
227     }
228   }
229   return ans;
230 }
231 void operator+=(BigNum &a,BigNum b)
232 {
233   a=a+b;
234 }
235 
236 BigNum operator*(BigNum a,BigNum b)
237 {
238   BigNum ans;
239   ans.s[0]=a.s[0]*b.s[0];           //乘法和除法的符号位简单处理
240   for(int i=1;i<a.len;i++)
241   {
242     for(int j=1;j<b.len;j++)
243     {
244       ans.s[i+j-1]+=a.s[i]*b.s[j];  //先存
245     }
246   }
247   int maxt=a.len+b.len;             //最多位数
248   for(int i=1;i<maxt;i++)           //处理每个位上的数
249   {
250     if(ans.s[i]>=10)
251     {
252       ans.s[i+1]+=ans.s[i]/10;
253       ans.s[i]=ans.s[i]%10;
254     }
255   }
256   int i;
257   for(i=maxt;i>1;i--)               //处理高位0
258   {
259     if(ans.s[i]!=0) break;
260   }
261   ans.len=i+1;
262   return ans;
263 }
264 void operator*=(BigNum &a,BigNum b)
265 {
266   a=a*b;
267 }
268 BigNum operator/(BigNum a,BigNum b)
269 {
270   /*
271     思路: 首先从a的高位往低位数,如果还<b,那么就再加1位,知道>=b,然后遍历1-9,判断此时
272         合适取值,和平常手动计算思路一样
273   */
274   BigNum ans;
275   ans.s[0]=a.s[0]*b.s[0];
276   b.s[0]=1;       //中途比较需要
277   BigNum tmp;     //添位取值
278   tmp.len=1;      //刚开始为无值,就是说连a的最高位都还没纳入
279   BigNum zj;      //中间变量,比较时需要,由于数组是倒置的,所以加这一变量
280   ans.len=1;      //答案还是空的
281   int j=a.len;    //j固定指向a,不断取值
282   bool match=1;   //match为0退出循环
283   while(1)
284   {
285     while(1)   //如果还没取够值,就继续加位
286     {
287       if(j==1)    //如果a到了符号位,那么可以退出循环了
288       {
289         match=0;
290         break;
291       }
292       tmp.s[tmp.len++]=a.s[--j]; //加位,由于开始不好确定位数,所以直接正向不好办
293       zj=tmp.Nizhi();            //数组颠倒后再去比较
294       if(b<=zj) break;           //如果b<=zj了,就可以退出了,否则该位为0
295       ans.s[ans.len++]=0;
296     }
297     if(!match) break;            //match为0退出循环
298     int i;
299     BigNum r=b;                  //r为最大容许的乘后值
300     for(i=2;i<=10;i++)
301     {
302       BigNum p;
303       p.s[p.len-1]=i;    //获得 2 - 10 . 赋值过程不符常规,但由于下一步是乘,可以忽略该bug
304       BigNum u=b*p;      //如果u超过了中间变量,可以退出了,同i应该减1
305       if(zj<u) break;
306       r=u;               //乘得的最大数
307     }
308     i--;
309     ans.s[ans.len++]=i;          //逐位求值
310     zj=zj-r;                     //获得余数
311     BigNum q;
312     if(zj==q) zj.len--;          //如果余数为0,那么去掉,不能出现00,不然会出错
313     tmp=zj.Nizhi();              //重新逆置
314   }
315   ans=ans.Nizhi();               //逆置获得答案
316   while(ans.s[ans.len-1]==0&&ans.len>2) //高位消0
317   {
318     ans.len--;
319   }
320   return ans;
321 }
322 void operator/=(BigNum &a,BigNum b)
323 {
324   a=a/b;
325 }
326 BigNum operator%(BigNum &a,BigNum b)
327 {
328   b.s[0]=1;
329   BigNum tmp;
330   tmp.len=1;
331   BigNum zj;
332   int j=a.len;
333   bool match=1;
334   while(1)
335   {
336     while(1)
337     {
338       if(j==1)
339       {
340         match=0;
341         break;
342       }
343       tmp.s[tmp.len++]=a.s[--j];
344       zj=tmp.Nizhi();
345       if(b<=zj) break;
346     }
347     if(!match) break;
348     int i;
349     BigNum r=b;
350     for(i=2;i<=10;i++)
351     {
352       BigNum p;
353       p.s[p.len-1]=i;
354       BigNum u=b*p;
355       if(zj<u) break;
356       r=u;
357     }
358     i--;
359     zj=zj-r;
360     BigNum q;
361     if(zj==q) zj.len--;
362     tmp=zj.Nizhi();
363   }
364   if(zj.len==1)
365   {
366     zj.Clear();
367   }
368   return zj;
369 }
370 void operator%=(BigNum &a,BigNum b)
371 {
372   a=a%b;
373 }
374 void BigNum::operator=(int a)
375 {
376   Clear();
377   if(a<0)
378   {
379     s[0]=-1;
380     a=-a;
381   }
382   len=1;
383   while(a)
384   {
385     s[len++]=a%10;
386     a/=10;
387   }
388 }
389 void BigNum::operator=(const char *a)
390 {
391   Clear();
392   if(*a=='-')
393   {
394     s[0]=-1;
395     a++;
396   }
397   len=1;
398   while(*a&&*a=='0') a++;
399   while(*a)
400   {
401     s[len++]=*a-'0';
402     a++;
403   }
404   if(len==1) len=2;
405   *this=Nizhi();
406 }
407 BigNum BigNum::operator--()   //  --a;
408 {
409   BigNum tmp;
410   tmp=-1;
411   *this+=tmp;
412   return *this;
413 }
414 BigNum BigNum::operator--(int)  // a--;
415 {
416   BigNum ans;
417   ans=*this;
418   BigNum tmp;
419   tmp=-1;
420   *this+=tmp;
421   return ans;
422 }
423 BigNum BigNum::operator++()  // ++a;
424 {
425   BigNum tmp;
426   tmp=1;
427   *this+=tmp;
428   return *this;
429 }
430 BigNum BigNum::operator++(int)  // a++;
431 {
432   BigNum ans;
433   ans=*this;
434   BigNum tmp;
435   tmp=1;
436   *this+=tmp;
437   return ans;
438 }
439 int main()
440 {
441 
442   return 0;
443 }

 

posted @ 2015-11-07 01:38  hchlqlz  阅读(274)  评论(0编辑  收藏  举报