码迷,mamicode.com
首页 > 其他好文 > 详细

大数模板 (C ++)

时间:2015-09-10 15:46:26      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

  上次BC遇到一个大数题目,没有大数模板和不会使用JAVA的同学们GG了,赛后从队友哪里骗出大数模板。2333333,真的炒鸡nice(就是有点长),贴出来分享一下好辣。

  1 //可以处理字符串前导零
  2 #include <iostream>
  3 #include <queue>
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <stack>
  8 using namespace std;
  9 #define maxn 120//大数的个数
 10 class DividedByZeroException {};
 11 
 12 class BigInteger
 13 {
 14 private:
 15     vector<char> digits;
 16     bool sign;          //  true for positive, false for negitive
 17     void trim();        //  remove zeros in tail, but if the value is 0, keep only one:)
 18 public:
 19     BigInteger(int);    // construct with a int integer
 20     BigInteger(string&) ;
 21     BigInteger();
 22     BigInteger (const BigInteger&);
 23     BigInteger operator=(const BigInteger& op2);
 24 
 25     BigInteger      abs() const;
 26     BigInteger    pow(int a);
 27 
 28     //binary operators
 29 
 30     friend BigInteger operator+=(BigInteger&,const BigInteger&);
 31     friend BigInteger operator-=(BigInteger&,const BigInteger&);
 32     friend BigInteger operator*=(BigInteger&,const BigInteger&);
 33     friend BigInteger operator/=(BigInteger&,const BigInteger&) throw(DividedByZeroException);
 34     friend BigInteger operator%=(BigInteger&,const BigInteger&) throw(DividedByZeroException);
 35 
 36     friend BigInteger operator+(const BigInteger&,const BigInteger&);
 37     friend BigInteger operator-(const BigInteger&,const BigInteger&);
 38     friend BigInteger operator*(const BigInteger&,const BigInteger&);
 39     friend BigInteger operator/(const BigInteger&,const BigInteger&) throw(DividedByZeroException);
 40     friend BigInteger operator%(const BigInteger&,const BigInteger&) throw(DividedByZeroException);
 41 
 42 
 43     //uniary operators
 44     friend BigInteger operator-(const BigInteger&);   //negative
 45 
 46     friend BigInteger operator++(BigInteger&);        //++v
 47     friend BigInteger operator++(BigInteger&,int);    //v++
 48     friend BigInteger operator--(BigInteger&);        //--v
 49     friend BigInteger operator--(BigInteger&,int);    //v--
 50 
 51     friend bool operator>(const BigInteger&,const BigInteger&);
 52     friend bool operator<(const BigInteger&,const BigInteger&);
 53     friend bool operator==(const BigInteger&,const BigInteger&);
 54     friend bool operator!=(const BigInteger&,const BigInteger&);
 55     friend bool operator>=(const BigInteger&,const BigInteger&);
 56     friend bool operator<=(const BigInteger&,const BigInteger&);
 57 
 58     friend ostream& operator<<(ostream&,const BigInteger&);    //print the BigInteger
 59     friend istream& operator>>(istream&, BigInteger&);         // input the BigInteger
 60 
 61 public:
 62     static const BigInteger ZERO;
 63     static const BigInteger ONE;
 64     static const BigInteger TEN;
 65 };
 66 // BigInteger.cpp
 67 
 68 const BigInteger BigInteger::ZERO=BigInteger(0);
 69 const BigInteger BigInteger::ONE =BigInteger(1);
 70 const BigInteger BigInteger::TEN =BigInteger(10);
 71 
 72 
 73 BigInteger::BigInteger()
 74 {
 75     sign=true;
 76 }
 77 
 78 
 79 BigInteger::BigInteger(int val) // construct with a int integer
 80 {
 81     if (val >= 0)
 82         sign = true;
 83     else
 84     {
 85         sign = false;
 86         val *= (-1);
 87     }
 88     do
 89     {
 90         digits.push_back( (char)(val%10) );
 91         val /= 10;
 92     }
 93     while ( val != 0 );
 94 }
 95 
 96 
 97 BigInteger::BigInteger(string& def)
 98 {
 99     sign=true;
100     for ( string::reverse_iterator iter = def.rbegin() ; iter < def.rend();  iter++)
101     {
102         char ch = (*iter);
103         if (iter == def.rend()-1)
104         {
105             if ( ch == + )
106                 break;
107             if(ch == - )
108             {
109                 sign = false;
110                 break;
111             }
112         }
113         digits.push_back( (char)((*iter) - 0 ) );
114     }
115     trim();
116 }
117 
118 void BigInteger::trim()
119 {
120     vector<char>::reverse_iterator iter = digits.rbegin();
121     while(!digits.empty() && (*iter) == 0)
122     {
123         digits.pop_back();
124         iter=digits.rbegin();
125     }
126     if( digits.size()==0 )
127     {
128         sign = true;
129         digits.push_back(0);
130     }
131 }
132 
133 
134 BigInteger::BigInteger(const BigInteger& op2)
135 {
136     sign = op2.sign;
137     digits=op2.digits;
138 }
139 
140 
141 BigInteger BigInteger::operator=(const BigInteger& op2)
142 {
143     digits = op2.digits;
144     sign = op2.sign;
145     return (*this);
146 }
147 
148 
149 BigInteger BigInteger::abs() const
150 {
151     if(sign)  return *this;
152     else      return -(*this);
153 }
154 
155 BigInteger BigInteger::pow(int a)
156 {
157     BigInteger res(1);
158     for(int i=0; i<a; i++)
159         res*=(*this);
160     return res;
161 }
162 
163 //binary operators
164 BigInteger operator+=(BigInteger& op1,const BigInteger& op2)
165 {
166     if( op1.sign == op2.sign )
167     {
168         //只处理相同的符号的情况,异号的情况给-处理
169         vector<char>::iterator iter1;
170         vector<char>::const_iterator iter2;
171         iter1 = op1.digits.begin();
172         iter2 = op2.digits.begin();
173         char to_add = 0;        //进位
174         while ( iter1 != op1.digits.end() && iter2 != op2.digits.end())
175         {
176             (*iter1) = (*iter1) + (*iter2) + to_add;
177             to_add = ((*iter1) > 9);    // 大于9进一位
178             (*iter1) = (*iter1) % 10;
179             iter1++;
180             iter2++;
181         }
182         while ( iter1 != op1.digits.end() )    //
183         {
184             (*iter1) = (*iter1) + to_add;
185             to_add = ( (*iter1) > 9 );
186             (*iter1) %= 10;
187             iter1++;
188         }
189         while ( iter2 != op2.digits.end() )
190         {
191             char val = (*iter2) + to_add;
192             to_add = (val > 9) ;
193             val %= 10;
194             op1.digits.push_back(val);
195             iter2++;
196         }
197         if( to_add != 0 )
198             op1.digits.push_back(to_add);
199         return op1;
200     }
201     else
202     {
203         if (op1.sign)
204             return op1 -= (-op2);
205         else
206             return op1= op2 - (-op1);
207     }
208 
209 }
210 
211 BigInteger operator-=(BigInteger& op1,const BigInteger& op2)
212 {
213     if( op1.sign == op2.sign )
214     {
215         //只处理相同的符号的情况,异号的情况给+处理
216         if(op1.sign)
217         {
218             if(op1 < op2)  // 2 - 3
219                 return  op1=-(op2 - op1);
220         }
221         else
222         {
223             if(-op1 > -op2)  // (-3)-(-2) = -(3 - 2)
224                 return op1=-((-op1)-(-op2));
225             else             // (-2)-(-3) = 3 - 2
226                 return op1= (-op2) - (-op1);
227         }
228         vector<char>::iterator iter1;
229         vector<char>::const_iterator iter2;
230         iter1 = op1.digits.begin();
231         iter2 = op2.digits.begin();
232 
233         char to_substract = 0;  //借位
234 
235         while ( iter1 != op1.digits.end() && iter2 != op2.digits.end())
236         {
237             (*iter1) = (*iter1) - (*iter2) - to_substract;
238             to_substract = 0;
239             if( (*iter1) < 0 )
240             {
241                 to_substract=1;
242                 (*iter1) += 10;
243             }
244             iter1++;
245             iter2++;
246         }
247         while ( iter1 != op1.digits.end() )
248         {
249             (*iter1) = (*iter1) - to_substract;
250             to_substract = 0;
251             if( (*iter1) < 0 )
252             {
253                 to_substract=1;
254                 (*iter1) += 10;
255             }
256             else break;
257             iter1++;
258         }
259         op1.trim();
260         return op1;
261     }
262     else
263     {
264         if (op1 > BigInteger::ZERO)
265             return op1 += (-op2);
266         else
267             return op1 = -(op2 + (-op1));
268     }
269 }
270 BigInteger operator*=(BigInteger& op1,const BigInteger& op2)
271 {
272     BigInteger result(0);
273     if (op1 == BigInteger::ZERO || op2==BigInteger::ZERO)
274         result = BigInteger::ZERO;
275     else
276     {
277         vector<char>::const_iterator iter2 = op2.digits.begin();
278         while( iter2 != op2.digits.end() )
279         {
280             if(*iter2 != 0)
281             {
282                 deque<char> temp(op1.digits.begin() , op1.digits.end());
283                 char to_add = 0;
284                 deque<char>::iterator iter1 = temp.begin();
285                 while( iter1 != temp.end() )
286                 {
287                     (*iter1) *= (*iter2);
288                     (*iter1) += to_add;
289                     to_add = (*iter1) / 10;
290                     (*iter1) %= 10;
291                     iter1++;
292                 }
293                 if( to_add != 0)
294                     temp.push_back( to_add );
295                 int num_of_zeros = iter2 - op2.digits.begin();
296                 while(  num_of_zeros--)
297                     temp.push_front(0);
298                 BigInteger temp2;
299                 temp2.digits.insert( temp2.digits.end() , temp.begin() , temp.end() );
300                 temp2.trim();
301                 result = result + temp2;
302             }
303             iter2++;
304         }
305         result.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
306     }
307     op1 = result;
308     return op1;
309 }
310 
311 BigInteger operator/=(BigInteger& op1 , const BigInteger& op2 ) throw(DividedByZeroException)
312 {
313     if( op2 == BigInteger::ZERO )
314         throw DividedByZeroException();
315     BigInteger t1 = op1.abs(), t2 = op2.abs();
316     if ( t1 < t2 )
317     {
318         op1 = BigInteger::ZERO;
319         return op1;
320     }
321     //现在 t1 > t2 > 0
322     //只需将 t1/t2的结果交给result就可以了
323     deque<char> temp;
324     vector<char>::reverse_iterator iter = t1.digits.rbegin();
325 
326     BigInteger temp2(0);
327     while( iter != t1.digits.rend() )
328     {
329         temp2 = temp2 * BigInteger::TEN + BigInteger( (int)(*iter) );
330         char s = 0;
331         while( temp2 >= t2 )
332         {
333             temp2 = temp2 - t2;
334             s = s + 1;
335         }
336         temp.push_front( s );
337         iter++;
338     }
339     op1.digits.clear();
340     op1.digits.insert( op1.digits.end() , temp.begin() , temp.end() );
341     op1.trim();
342     op1.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
343     return op1;
344 }
345 
346 BigInteger operator%=(BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
347 {
348     return op1 -= ((op1 / op2)*op2);
349 }
350 
351 BigInteger operator+(const BigInteger& op1,const BigInteger& op2)
352 {
353     BigInteger temp(op1);
354     temp += op2;
355     return temp;
356 }
357 BigInteger operator-(const BigInteger& op1,const BigInteger& op2)
358 {
359     BigInteger temp(op1);
360     temp -= op2;
361     return temp;
362 }
363 
364 BigInteger operator*(const BigInteger& op1,const BigInteger& op2)
365 {
366     BigInteger temp(op1);
367     temp *= op2;
368     return temp;
369 
370 }
371 
372 BigInteger operator/(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
373 {
374     BigInteger temp(op1);
375     temp /= op2;
376     return temp;
377 }
378 
379 BigInteger operator%(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
380 {
381     BigInteger temp(op1);
382     temp %= op2;
383     return temp;
384 }
385 
386 //uniary operators
387 BigInteger operator-(const BigInteger& op)    //negative
388 {
389     BigInteger temp = BigInteger(op);
390     temp.sign = !temp.sign;
391     return temp;
392 }
393 
394 BigInteger operator++(BigInteger& op)     //++v
395 {
396     op += BigInteger::ONE;
397     return op;
398 }
399 
400 BigInteger operator++(BigInteger& op,int x)   //v++
401 {
402     BigInteger temp(op);
403     ++op;
404     return temp;
405 }
406 
407 BigInteger operator--(BigInteger& op)     //--v
408 {
409     op -=  BigInteger::ONE;
410     return op;
411 }
412 
413 BigInteger operator--(BigInteger& op,int x)   //v--
414 {
415     BigInteger temp(op);
416     --op;
417     return temp;
418 }
419 
420 bool operator<(const BigInteger& op1,const BigInteger& op2)
421 {
422     if( op1.sign != op2.sign )
423         return !op1.sign;
424     else
425     {
426         if(op1.digits.size() != op2.digits.size())
427             return (op1.sign && op1.digits.size()<op2.digits.size())
428                    || (!op1.sign && op1.digits.size()>op2.digits.size());
429         vector<char>::const_reverse_iterator iter1,iter2;
430         iter1 = op1.digits.rbegin();
431         iter2 = op2.digits.rbegin();
432         while( iter1 != op1.digits.rend() )
433         {
434             if(  op1.sign &&  *iter1 < *iter2 ) return true;
435             if(  op1.sign &&  *iter1 > *iter2 ) return false;
436             if( !op1.sign &&  *iter1 > *iter2 ) return true;
437             if( !op1.sign &&  *iter1 < *iter2 ) return false;
438             iter1++;
439             iter2++;
440         }
441         return false;
442     }
443 }
444 bool operator==(const BigInteger& op1,const BigInteger& op2)
445 {
446     if( op1.sign != op2.sign  || op1.digits.size() != op2.digits.size() )
447         return false;
448     vector<char>::const_iterator iter1,iter2;
449     iter1 = op1.digits.begin();
450     iter2 = op2.digits.begin();
451     while( iter1!= op1.digits.end() )
452     {
453         if( *iter1 != *iter2 )  return false;
454         iter1++;
455         iter2++;
456     }
457     return true;
458 }
459 
460 bool operator!=(const BigInteger& op1,const BigInteger& op2)
461 {
462     return !(op1==op2);
463 }
464 
465 bool operator>=(const BigInteger& op1,const BigInteger& op2)
466 {
467     return (op1>op2) || (op1==op2);
468 }
469 
470 bool operator<=(const BigInteger& op1,const BigInteger& op2)
471 {
472     return (op1<op2) || (op1==op2);
473 }
474 
475 bool operator>(const BigInteger& op1,const BigInteger& op2)
476 {
477     return !(op1<=op2);
478 }
479 
480 ostream& operator<<(ostream& stream,const BigInteger& val)     //print the BigInteger
481 {
482     if (!val.sign)
483         stream << "-";
484     for ( vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++)
485         stream << (char)((*iter) + 0);
486     return stream;
487 }
488 
489 istream& operator>>(istream& stream, BigInteger& val)
490 {
491     //Input the BigInteger
492     string str;
493     stream >> str;
494     val=BigInteger(str);
495     return stream;
496 }
497 BigInteger a;
498 //定义一个大数a

在Hdu上要用G++提交,C++提交会CE,亲测!!!!

大数模板 (C ++)

标签:

原文地址:http://www.cnblogs.com/alihenaixiao/p/4797891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!