大数模板 (C ++)
上次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,亲测!!!!
本文为博主原创文章,未经博主允许不得转载。