Fork me on GitHub

大数模板(正整数)

找大数模板的时候发现大部分模板功能不全,或者代码过于冗长,或者函数实现复杂度较高。

于是在现有模板的基础上整理以及优化,写出了下面的大数模板。

一、基本功能

支持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 }

 

 

关于支持位运算的二进制存储大数模板,以后有空的化也弄一个出来吧。

posted @ 2018-10-16 01:26  Xenny  阅读(1468)  评论(0编辑  收藏  举报