大数模板(正整数)
找大数模板的时候发现大部分模板功能不全,或者代码过于冗长,或者函数实现复杂度较高。
于是在现有模板的基础上整理以及优化,写出了下面的大数模板。
一、基本功能
支持int,long long,string和C字符串拷贝构造。
支持常规四则运算和求模运算,但不支持大数相除以及大数求模。
重载了流,支持cin,cout输入输出。
支持自增,自减,左移,右移,比较,支持+=等形式。
除法和求模只支持对int或者long long类型,不是我懒,模拟除法和求模太烧脑,而且时空复杂度都比较高。
特别的重载了^,并非异或,而是求幂运算。
函数能优化的地方基本都优化了,特别的是用int数组存储,每位最大存储9999,降低空间复杂度。
每位存储位数,最大长度等都可以自行更改。
二、函数定义
- void print(); //输出大数
- int Size(); //返回大数长度
- int the_first(); //返回第一个数字
- int the_last(); //返回最后一位数字
- int to_int(); //转化为整数
- long long int to_long();
- string to_String(); //转化为string类型
定义了以上函数。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 9999 5 #define MAXSIZE 500 //最大长度 6 #define DLEN 4 7 8 class BigNum 9 { 10 private: 11 int a[210]; //控制大数的位数 12 int len; //长度 13 public: 14 BigNum(){ len = 1;memset(a,0,sizeof(a)); } //构造函数 15 void XD(); 16 BigNum(const int); 17 BigNum(const long long int); 18 BigNum(const char*); 19 BigNum(const string &); 20 BigNum(const BigNum &); //拷贝构造函数 21 BigNum &operator = (const BigNum &); //重载赋值运算符 22 BigNum &operator = (const int &); 23 BigNum &operator = (const long long int &); 24 25 friend istream& operator >> (istream&, BigNum&); //重载输入运算符 26 friend ostream& operator << (ostream&, BigNum&); //重载输出运算符 27 28 template<typename T> BigNum operator << (const T &) const; 29 template<typename T> BigNum operator >> (const T &) const; 30 31 BigNum operator + (const BigNum &) const; //重载加法运算符,大数加大数 32 BigNum operator - (const BigNum &) const; //重载减法运算符,大数减大数 33 BigNum operator * (const BigNum &) const; //重载乘法运算符,大数乘大数 34 bool operator > (const BigNum& b)const; //重载大于 35 bool operator < (const BigNum& b) const; //重载小于 36 bool operator == (const BigNum& b) const; //重载等于符号 37 template<typename T> BigNum operator / (const T &) const; //重载除法运算符,大数除整数 38 template<typename T> BigNum operator ^ (const T &) const; //大数的n次方 39 template<typename T> T operator % (const T &) const; //大数对int取模 40 41 template<typename T> BigNum operator + (const T& b) const {BigNum t = b; t = *this + t; return t;} 42 template<typename T> BigNum operator - (const T& b) const {BigNum t = b; t = *this - t; return t;} 43 template<typename T> BigNum operator * (const T& b) const {BigNum t = b; t = (*this) * t; return t;} 44 template<typename T> bool operator < (const T& b) const {BigNum t = b; return ((*this) < t);} 45 template<typename T> bool operator > (const T& b) const {BigNum t = b; return ((*this) > t);} 46 template<typename T> bool operator == (const T& b) const {BigNum t = b; return ((*this) == t);} 47 48 bool operator <= (const BigNum& b) const {return (*this) < b || (*this) == b;} 49 bool operator >= (const BigNum& b) const {return (*this) > b || (*this) == b;} 50 bool operator != (const BigNum& b) const {return !((*this) == b);} 51 52 template<typename T> bool operator >= (const T& b) const {BigNum t = b; return !((*this) < t);} 53 template<typename T> bool operator <= (const T& b) const {BigNum t = b; return !((*this) > t);} 54 template<typename T> bool operator != (const T& b) const {BigNum t = b; return !((*this) == t);} 55 56 BigNum& operator += (const BigNum& b) {*this = *this + b; return *this;} 57 BigNum& operator -= (const BigNum& b) {*this = *this - b; return *this;} 58 BigNum& operator *= (const BigNum& b) {*this = *this * b; return *this;} 59 template<typename T> BigNum& operator /= (const T& b) {*this = *this/b; return *this;} 60 template<typename T> BigNum& operator %= (const T& b) {*this = *this%b; return *this;} 61 template<typename T> BigNum& operator += (const T& b) {*this = *this+b; return *this;} 62 template<typename T> BigNum& operator -= (const T& b) {*this = *this-b; return *this;} 63 template<typename T> BigNum& operator *= (const T& b) {*this = *this*b; return *this;} 64 template<typename T> BigNum& operator ^= (const T& b) {*this = *this^b; return *this;} 65 66 BigNum operator ++ (int) {BigNum t = *this; *this += 1; return t;} 67 BigNum operator -- (int) {BigNum t = *this; *this -= 1; return t;} 68 BigNum& operator -- () {*this -= 1; return *this;} 69 BigNum& operator ++ () {*this += 1; return *this;} 70 71 template<typename T> BigNum& operator <<= (const T& b) {*this = *this << b; return *this;} 72 template<typename T> BigNum& operator >>= (const T& b) {*this = *this >> b; return *this;} 73 74 template<typename T> BigNum friend operator + (const T& a, const BigNum& b) {BigNum t = a; t = t + a; return t;} 75 template<typename T> BigNum friend operator - (const T& a, const BigNum& b) {BigNum t = a; t = t - b; return t;} 76 template<typename T> BigNum friend operator * (const T& a, const BigNum& b) {BigNum t = a; t = t * b; return t;} 77 template<typename T> friend bool operator < (const T& a, const BigNum& b) {return b > a;} 78 template<typename T> friend bool operator > (const T& a, const BigNum& b) {return b < a;} 79 template<typename T> friend bool operator <= (const T& a, const BigNum& b) {return b >= a;} 80 template<typename T> friend bool operator >= (const T& a, const BigNum& b) {return b <= a;} 81 template<typename T> friend bool operator == (const T& a, const BigNum& b) {return b == a;} 82 template<typename T> friend bool operator != (const T& a, const BigNum& b) {return b != a;} 83 84 void print(); //输出大数 85 int Size(); //返回大数长度 86 int the_first(); //返回第一个数字 87 int the_last(); //返回最后一位数字 88 int to_int(); //转化为整数 89 long long int to_long(); 90 string to_String(); //转化为string类型 91 //char* to_char(); 92 }; 93 94 BigNum::BigNum(const int b) //将一个int类型的变量转化为大数 95 { 96 int c,d = b; 97 len = 0; 98 memset(a,0,sizeof(a)); 99 while(d > MAXN){ 100 c = d - (d / (MAXN+1)) * (MAXN+1); 101 d = d / (MAXN+1); 102 a[len++] = c; 103 } 104 a[len++] = d; 105 } 106 BigNum::BigNum(const long long int b) 107 { 108 long long int c,d = b; 109 len = 0; 110 memset(a,0,sizeof(a)); 111 while(d > MAXN){ 112 c = d - (d / (MAXN+1)) * (MAXN+1); 113 d = d / (MAXN+1); 114 a[len++] = c; 115 } 116 a[len++] = d; 117 } 118 BigNum::BigNum(const string& s) 119 { 120 int t,k,index,l,i; 121 memset(a,0,sizeof(a)); 122 l = s.size(); 123 len = l/DLEN; 124 if(l%DLEN) 125 len++; 126 index = 0; 127 for(i = l-1; i >=0 ;i -= DLEN){ 128 t = 0; 129 k = i-DLEN+1; 130 if(k < 0) k = 0; 131 for(int j = k; j <= i; j++) 132 t = t*10 + s[j]-'0'; 133 a[index++] = t; 134 } 135 } 136 BigNum::BigNum(const char* s) //将一个字符串类型的变量转化为大数 137 { 138 int t,k,index,l,i; 139 memset(a,0,sizeof(a)); 140 l = strlen(s); 141 len = l/DLEN; 142 if(l%DLEN) 143 len++; 144 index = 0; 145 for(i = l-1; i >= 0; i -= DLEN){ 146 t = 0; 147 k = i - DLEN + 1; 148 if(k < 0) k = 0; 149 for(int j = k; j <= i; j++) 150 t = t*10 + s[j] - '0'; 151 a[index++] = t; 152 } 153 } 154 BigNum::BigNum(const BigNum & b) : len(b.len) //拷贝构造函数 155 { 156 memset(a,0,sizeof(a)); 157 for(int i = 0 ; i < len ; i++) 158 a[i] = b.a[i]; 159 } 160 BigNum & BigNum::operator = (const BigNum& n) //重载赋值运算符,大数之间进行赋值运算 161 { 162 len = n.len; 163 memset(a,0,sizeof(a)); 164 for(int i = 0 ; i < len ; i++) 165 a[i] = n.a[i]; 166 return *this; 167 } 168 BigNum & BigNum::operator = (const int& num) 169 { 170 BigNum t(num); 171 *this = t; 172 return *this; 173 } 174 BigNum & BigNum::operator = (const long long int& num) 175 { 176 BigNum t(num); 177 *this = t; 178 return *this; 179 } 180 void XD() 181 { 182 cout << "A hidden egg! Good luck for u!" << endl; 183 } 184 istream& operator >> (istream & in, BigNum & b) //重载输入运算符 185 { 186 char ch[MAXSIZE*4]; 187 int i = -1; 188 in>>ch; 189 int l = strlen(ch); 190 int cnt = 0, sum = 0; 191 for(i = l-1; i >= 0; ){ 192 sum = 0; 193 int t = 1; 194 for(int j = 0; j < 4 && i >= 0; j++,i--,t *= 10) 195 sum += (ch[i]-'0')*t; 196 b.a[cnt] = sum; 197 cnt++; 198 } 199 b.len = cnt++; 200 return in; 201 202 } 203 ostream& operator << (ostream& out, BigNum& b) //重载输出运算符 204 { 205 int i; 206 cout << b.a[b.len - 1]; 207 for(i = b.len - 2 ; i >= 0 ; i--){ 208 cout.width(DLEN); 209 cout.fill('0'); 210 cout << b.a[i]; 211 } 212 return out; 213 } 214 215 template<typename T> BigNum BigNum::operator << (const T& b) const 216 { 217 T temp = 1; 218 for(int i = 0; i < b; i++) 219 temp *= 2; 220 BigNum t = (*this) * temp; 221 return t; 222 } 223 template<typename T> BigNum BigNum::operator >> (const T& b) const 224 { 225 T temp = 1; 226 for(int i = 0; i < b; i++) 227 temp *= 2; 228 BigNum t = (*this) / temp; 229 return t; 230 } 231 232 BigNum BigNum::operator + (const BigNum& b) const //两个大数之间的相加运算 233 { 234 BigNum t(*this); 235 int i,big; 236 big = b.len > len ? b.len : len; 237 for(i = 0 ; i < big ; i++){ 238 t.a[i] += b.a[i]; 239 if(t.a[i] > MAXN){ 240 t.a[i + 1]++; 241 t.a[i] -=MAXN+1; 242 } 243 } 244 if(t.a[big] != 0) 245 t.len = big + 1; 246 else 247 t.len = big; 248 return t; 249 } 250 BigNum BigNum::operator - (const BigNum& b) const //两个大数之间的相减运算 251 { 252 int i,j,big; 253 bool flag; 254 BigNum t1,t2; 255 if(*this>b){ 256 t1 = *this; 257 t2 = b; 258 flag = 0; 259 } 260 else{ 261 t1 = b; 262 t2 = *this; 263 flag = 1; 264 } 265 big = t1.len; 266 for(i = 0 ; i < big ; i++){ 267 if(t1.a[i] < t2.a[i]){ 268 j = i + 1; 269 while(t1.a[j] == 0) 270 j++; 271 t1.a[j--]--; 272 while(j > i) 273 t1.a[j--] += MAXN; 274 t1.a[i] += MAXN + 1 - t2.a[i]; 275 } 276 else 277 t1.a[i] -= t2.a[i]; 278 } 279 t1.len = big; 280 while(t1.a[t1.len - 1] == 0 && t1.len > 1){ 281 t1.len--; 282 big--; 283 } 284 if(flag) 285 t1.a[big-1] = 0-t1.a[big-1]; 286 return t1; 287 } 288 289 BigNum BigNum::operator * (const BigNum& b) const //两个大数之间的相乘运算 290 { 291 BigNum ret; 292 int i,j,up; 293 int temp,temp1; 294 for(i = 0 ; i < len ; i++){ 295 up = 0; 296 for(j = 0 ; j < b.len ; j++){ 297 temp = a[i] * b.a[j] + ret.a[i + j] + up; 298 if(temp > MAXN){ 299 temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); 300 up = temp / (MAXN + 1); 301 ret.a[i + j] = temp1; 302 } 303 else{ 304 up = 0; 305 ret.a[i + j] = temp; 306 } 307 } 308 if(up != 0) ret.a[i + j] = up; 309 } 310 ret.len = i + j; 311 while(ret.a[ret.len - 1] == 0 && ret.len > 1) 312 ret.len--; 313 return ret; 314 } 315 template<typename T> BigNum BigNum::operator / (const T& b) const 316 { 317 BigNum ret; 318 T i,down = 0; 319 for(i = len - 1 ; i >= 0 ; i--){ 320 ret.a[i] = (a[i] + down * (MAXN + 1)) / b; 321 down = a[i] + down * (MAXN + 1) - ret.a[i] * b; 322 } 323 ret.len = len; 324 while(ret.a[ret.len - 1] == 0 && ret.len > 1) 325 ret.len--; 326 return ret; 327 } 328 template<typename T> T BigNum::operator % (const T& b) const 329 { 330 T i,d=0; 331 for (i = len-1; i>=0; i--){ 332 d = ((d * (MAXN+1))% b + a[i])% b; 333 } 334 return d; 335 } 336 337 338 template<typename T> BigNum BigNum::operator^(const T& n) const //大数的n次方运算 339 { 340 BigNum t,ret(1); 341 int i; 342 if(n < 0) return 0; 343 if(n == 0) 344 return 1; 345 if(n == 1) 346 return *this; 347 int m = n; 348 while(m > 1){ 349 t =* this; 350 for(i = 1; (i<<1) <= m;i <<= 1) 351 t = t*t; 352 m-=i; 353 ret=ret*t; 354 if(m == 1) ret = ret * (*this); 355 } 356 return ret; 357 } 358 359 bool BigNum::operator > (const BigNum& b) const //大数和另一个大数的大小比较 360 { 361 int tot; 362 if(len > b.len) 363 return true; 364 else if(len == b.len){ 365 tot = len - 1; 366 while(a[tot] == b.a[tot] && tot >= 0) 367 tot--; 368 if(tot >= 0 && a[tot] > b.a[tot]) 369 return true; 370 else 371 return false; 372 } 373 else 374 return false; 375 } 376 377 bool BigNum::operator < (const BigNum& b) const 378 { 379 int tot; 380 if(len > b.len) 381 return false; 382 else if(len == b.len){ 383 tot = len - 1; 384 while(a[tot] == b.a[tot] && tot >= 0) 385 tot--; 386 if(tot >= 0 && a[tot] > b.a[tot]) 387 return false; 388 else 389 return false; 390 } 391 else 392 return true; 393 } 394 395 bool BigNum::operator == (const BigNum& b) const 396 { 397 int tot = len-1; 398 if(len != b.len) 399 return false; 400 while(a[tot] == b.a[tot] && tot >= 0) 401 tot--; 402 if(tot < 0) 403 return true; 404 return false; 405 } 406 407 void BigNum::print() //输出大数 408 { 409 int i; 410 cout << a[len - 1]; 411 for(i = len-2; i >= 0; i--){ 412 cout.width(DLEN); 413 cout.fill('0'); 414 cout << a[i]; 415 } 416 cout << endl; 417 } 418 int BigNum::Size() 419 { 420 int t = a[len-1],cnt = 0; 421 while(t){ t /= 10; cnt++; } 422 cnt += (len-1)*4; 423 return cnt; 424 } 425 int BigNum::the_first() 426 { 427 int t = a[len-1]; 428 while(t > 10){ t /= 10;} 429 return t; 430 } 431 int BigNum::the_last() 432 { 433 int t = a[0]; 434 return t%10; 435 } 436 int BigNum::to_int() 437 { 438 int i,num; 439 num = a[len-1]; 440 for(i = len-2; i >= 0; i--) 441 num = num*(MAXN+1) + a[i]; 442 return num; 443 } 444 long long int BigNum::to_long() 445 { 446 int i; 447 long long int num; 448 num = a[len-1]; 449 for(i = len-2; i >= 0; i--) 450 num = num*(MAXN+1) + a[i]; 451 return num; 452 } 453 string BigNum::to_String() 454 { 455 int i; 456 string s = "",tp = ""; 457 s += to_string(a[len-1]); 458 for(i = len-2; i >= 0; i--){ 459 tp = to_string(a[i]); 460 int tot = tp.size(); 461 tp.insert(tp.begin(),4-tot,'0'); 462 s = s + tp; 463 } 464 return s; 465 } 466 int main() 467 { 468 BigNum a,b; 469 }
关于支持位运算的二进制存储大数模板,以后有空的化也弄一个出来吧。