zoukankan      html  css  js  c++  java
  • 大数模板(正整数)

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

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

    一、基本功能

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

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

  • 相关阅读:
    Redis源码阅读笔记(2)——字典(Map)实现原理
    Partition List ——LeetCode
    docker format (golang template)
    markdown 换行
    pecan快速教程
    nvdimm
    k8s device plugin
    linux 文件同步
    复制MIFARE Classic卡
    install docker swarm on centos
  • 原文地址:https://www.cnblogs.com/xenny/p/9795721.html
Copyright © 2011-2022 走看看