• 大整数处理类(cpp文件)


    ///////////////////////integer.cpp

    #include "integer.h"

    BigInteger::BigInteger()

    {

        sign = 0;

        ndigit = 1;

        modulus[0] = '0';

        memset(modulus + 1,'\0',MAXSIZE - 1);

    }

     

    BigInteger::~BigInteger()

    {

     

    }

     

    BigInteger::BigInteger(const char* a)

    {

        memset(modulus,'\0',MAXSIZE);

     

        sign = (a[0] == '-') ? 1 : 0;

     

        int pos = sign;

     

        while('\0' != a[pos])

        {

           modulus[pos - sign] = a[pos++];

        }

     

        ndigit = pos - sign;

     

        modulus[ndigit] = '\0';

    }

     

    BigInteger::BigInteger(const int& another)

    {

        memset(modulus,'\0',MAXSIZE);

     

        int an = another;

        if(0 == an)

        {

           sign = 0;

           ndigit = 1;

           modulus[0] = '0';

           modulus[1] = '\0';

           return;

        }

        else if(an > 0)

           sign = 0;

        else

        {

           sign = 1;

           an = -an;

        }

        int tmp[256] = {0};

     

        int i = 0;

        while(0 < an)

        {

           tmp[i++] = an % 10;

           an /= 10;

        }

        ndigit = i;

        for(i = 0;i < ndigit;i++)

        {

           modulus[i] = tmp[ndigit - 1 - i] + '0';

        }

        modulus[ndigit] = '\0';

    }

     

    BigInteger::BigInteger(const BigInteger& another)

    {

        memset(modulus,'\0',MAXSIZE);

        sign = another.sign;

        ndigit = another.ndigit;

        memcpy(modulus,another.modulus,another.ndigit);

    }

     

    BigInteger BigInteger::abs(const BigInteger& another)

    {

        BigInteger newBigInteger = another;

        newBigInteger.sign = 0;

        return newBigInteger;

    }

    BigInteger BigInteger::mod(const BigInteger& another)

    {

        return (*this % another);

    }

    BigInteger BigInteger::gcd(const BigInteger& another)

    {

        return (gcd(*this,another));

    }

    BigInteger BigInteger::gcd(const BigInteger& a1, const BigInteger& a2)

    {

        if((BigInteger("0") == a1) || (BigInteger("0") == a2))

        {

           BigInteger result;

           memcpy(result.modulus,"error",6);

           return result;

        }

        BigInteger a = abs(a1);

        BigInteger b = abs(a2);

        BigInteger c;

        if(a < b)

        {

           c = a;

           a = b;

           b = c;

        }

        while(b > BigInteger("0"))

        {

           c = a % b;

           a = b;

           b = c;

        }

        return a;

    }

    BigInteger BigInteger::lcm(const BigInteger& another)

    {

        return (lcm(*this,another));

    }

    BigInteger BigInteger::lcm(const BigInteger& a1, const BigInteger& a2)

    {

        if((BigInteger("0") == a1) || (BigInteger("0") == a2))

        {

           return BigInteger("0");

        }

        BigInteger a = a1;

        BigInteger b = a2;

        return (a * b / gcd(a,b));

    }

    BigInteger& BigInteger::operator = (const BigInteger& another)

    {

        sign = another.sign;

        ndigit = another.ndigit;

        memcpy(modulus,another.modulus,MAXSIZE);

     

        return *this;

    }

     

    BigInteger& BigInteger::operator = (const string& another)

    {

        sign = (another[0] == '-') ? 1 : 0;

     

        int pos = sign;

     

        while('\0' != another[pos])

        {

           modulus[pos - sign] = another[pos++];

        }

     

        ndigit = pos - sign;

        modulus[ndigit] = '\0';

     

        return *this;

    }

     

    BigInteger& BigInteger::operator = (const int& another)

    {

        int an = another;

        if(0 == an)

        {

           sign = 0;

           ndigit = 1;

           modulus[0] = '0';

           modulus[1] = '\0';

           return *this;

        }

        else if(an > 0)

           sign = 0;

        else

        {

           sign = 1;

           an = -an;

        }

        int tmp[256] = {0};

     

        int i = 0;

        while(0 < an)

        {

           tmp[i++] = an % 10;

           an /= 10;

        }

        ndigit = i;

        for(i = 0;i < ndigit;i++)

        {

           modulus[i] = tmp[ndigit - 1 - i] + '0';

        }

        modulus[ndigit] = '\0';

     

        return *this;

    }

    /**

    * 重载+运算符(-,*,/,%与其相同)

     

    * 这里应该是值返回,因为值返回会产生临时变量,临时变量与局部变量result的复制

    会进入到拷贝构造函数中,重新拷贝一份,局部变量result在运行完拷贝构造函数后才

    会被释放掉;

    若返回引用,则不会产生临时变量,函数结束后不会进入到拷贝构造函数,而函数运

    行结束后,result变量已经被释放,即返回值所引用的对象已经被释放,就会指向一个

    无效的值,即结果错误。

     

    @param another 进行加运算的第二个操作符

     

    @return 运算的结果

    */ 

    BigInteger BigInteger::operator + (const BigInteger& another)

    {

        bool signSame = !(sign ^ another.sign);

     

        if(signSame)

        {

           if(0 == sign)

           {

               BigInteger result;

               int nlunker = max(ndigit,another.ndigit);

     

               int residue = 0;

               for(int i = 0;i < nlunker;++i)

               {

                  int a1 = ((ndigit - 1 - i) >= 0) ? (modulus[ndigit - 1 - i] - '0') : 0;

                  int a2 = ((another.ndigit - 1 - i) >= 0) ? (another.modulus[another.ndigit - 1 - i] - '0') : 0;

                  residue += a1 + a2;

     

                  result.modulus[nlunker - i] = (residue % 10) + '0';

                  residue /= 10;

               }

               if(residue > 0)

               {

                  result.modulus[0] = residue + '0';

                  result.sign = 0;

                  result.ndigit = nlunker + 1;

                  result.modulus[result.ndigit] = '\0';

                  return result;

               }

               else

               {

                  BigInteger r1;

                  r1.sign = 0;

                  r1.ndigit = nlunker;

                  memcpy(r1.modulus,result.modulus+1,nlunker);

     

                  r1.modulus[r1.ndigit] = '\0';

                  return r1;

               }

           }

           else

           {

               BigInteger a1 = *this;

               BigInteger a2 = another;

               a1.sign = a2.sign = 0;

     

               return -(a1 + a2);

           }

        }

        else

        {

           if(0 == sign)

           {

               BigInteger a2 = *this;

               BigInteger a1 = another;

               a1.sign = 0;

               return a2 - a1;

           }

           else

           {

               BigInteger a2 = another;

               BigInteger a1 = *this;

               a1.sign = 0;

               return a2 - a1;

           }

        }

    }

     

    BigInteger& BigInteger::operator += (const BigInteger& another)

    {

        *this = *this + another;

        return *this;

    }

     

    BigInteger BigInteger::operator - (const BigInteger& another)

    {

        bool signSame = !(sign ^ another.sign);

        if(signSame)

        {

           if(abs(*this) >= abs(another))

           {

               if(0 == sign)

               {

                  BigInteger result;

                  int nlunker = max(ndigit,another.ndigit);

     

                  int residue = 0;

                  for(int i = 0;i < nlunker;++i)

                  {

                      int a1 = ((ndigit - 1 - i) >= 0) ? (modulus[ndigit - 1 - i] - '0') : 0;

                      int a2 = ((another.ndigit - 1 - i) >= 0) ? (another.modulus[another.ndigit - 1 - i] - '0') : 0;

                      int temp = residue + a1 - a2;

                      if(temp < 0)

                      {

                         result.modulus[nlunker - 1 - i] = ((temp + 10) % 10) + '0';

                         residue = -1;

                      }

                      else

                      {

                         result.modulus[nlunker - 1 - i] = (temp % 10) + '0';

                         residue = 0;

                      }

                  }

                  BigInteger newBigInteger;

                  int nZero = 0;

                  while('0' == result.modulus[nZero])

                      nZero++;

                  newBigInteger.ndigit = nlunker - nZero;

                  if(0 == newBigInteger.ndigit)

                  {

                      newBigInteger.ndigit = 1;

                      newBigInteger.modulus[0] = '0';

                      newBigInteger.modulus[1] = '\0';

                  }

                  else

                  {

                      memcpy(newBigInteger.modulus,result.modulus + nZero,newBigInteger.ndigit);

                      newBigInteger.modulus[newBigInteger.ndigit] = '\0';

                  }

                  newBigInteger.sign = 0;

     

                  return newBigInteger;

               }

               else

               {

                  BigInteger a1 = *this;

                  BigInteger a2 = another;

                  a1.sign = a2.sign = 0;

     

                  return -(a1 - a2);

               }

           }

           else

           {

               if(0 == sign)

               {

                  BigInteger a1 = *this;

                  BigInteger a2 = another;

                  return -(a2 - a1);

               }

               else

               {

                  BigInteger a1 = *this;

                  BigInteger a2 = another;

                  a1.sign = a2.sign = 0;

     

                  return a2 - a1;

               }

           }

        }

        else

        {

           if(0 == sign)

           {

               BigInteger a1 = *this;

               BigInteger a2 = another;

               a2.sign = 0;

               return a1 + a2;

           }

           else

           {

               BigInteger a1 = *this;

               BigInteger a2 = another;

               a1.sign = 0;

               return -(a1 + a2);

           }

        }

        BigInteger result;

     

        return result;

    }

     

    BigInteger& BigInteger::operator -= (const BigInteger& another)

    {

        *this = *this - another;

        return *this;

    }

     

    BigInteger BigInteger::operator - ()

    {

        BigInteger newBigInteger = *this;

        newBigInteger.sign = !newBigInteger.sign;

        return newBigInteger;

    }

     

    BigInteger BigInteger::operator * (const BigInteger& another)

    {

        if((BigInteger("0") == *this) || (BigInteger("0") == another))

        {

           return BigInteger("0");

        }

     

        bool signSame = !(sign ^ another.sign);

        BigInteger result;

        int temp[MAXSIZE] = {0};

     

        BigInteger a1 = *this;

        BigInteger a2 = another;

     

        int i,j;

        for(i = 0;i < a1.ndigit;i++)

           for(j = 0;j < a2.ndigit;j++)

           {

               temp[i + j] += (a1.modulus[a1.ndigit - 1 - i] - '0') * (a2.modulus[a2.ndigit - 1 - j] - '0');

           }

           int residue = 0;

           for(i = 0;i < a1.ndigit + a2.ndigit - 1;i++)

           {

               temp[i + 1] += temp[i] / 10;

               temp[i] %= 10;

           }

           result.ndigit = (temp[a1.ndigit + a2.ndigit - 1] > 0) ? (a1.ndigit + a2.ndigit) : (a1.ndigit + a2.ndigit - 1);

     

           for(i = 0;i < result.ndigit;i++)

           {

               result.modulus[i] = temp[result.ndigit - 1 - i] + '0';

           }

           result.modulus[result.ndigit] = '\0';

           result.sign = signSame ? 0 : 1;

     

           return result;

    }

     

    BigInteger& BigInteger::operator *= (const BigInteger& another)

    {

        *this = *this * another;

        return *this;

    }

    BigInteger BigInteger::operator / (const BigInteger& another)

    {

        BigInteger result;

        if('0' == another.modulus[0])

        {

           memcpy(result.modulus,"error",6);

           return result;

        }

     

        bool signSame = !(sign ^ another.sign);

        if(abs(*this) < abs(another))

           return BigInteger("0");

        else if(abs(*this) == abs(another))

        {

           if(signSame)

               return BigInteger("1");

           else

               return BigInteger("-1");

        }

        else

        {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           a1.sign = a2.sign = 0;

           BigInteger coe("-1");

           if(signSame)

               coe.sign = 0;

     

           if((a1.ndigit - a2.ndigit) <= 1)

           {

               int w = 0;

               while(a1 >= a2)

               {

                  w++;

                  a1 -= a2;

               }

               return (coe*BigInteger(w));

           }

           else

           {

               int w = a1.ndigit - a2.ndigit;

               BigInteger times;

               times.ndigit = w + 1;

               times.sign = 0;

               times.modulus[0] = '1';

               memset(times.modulus + 1,'0',w);

               times.modulus[times.ndigit] = '\0';

               if(a1 < (a2 * times))

               {

                  times.ndigit = w;

                  times.modulus[times.ndigit] = '\0';

               }

               return (coe*times + (coe*(a1 - a2 * times) / a2));

           }

        }

    }

     

     

     

    BigInteger& BigInteger::operator /= (const BigInteger& another)

    {

        *this = *this / another;

        return *this;

    }

    BigInteger BigInteger::operator % (const BigInteger& another)

    {

        BigInteger result;

        result = *this - (*this / another) * another;

        return result;

    }

    BigInteger& BigInteger::operator %= (const BigInteger& another)

    {

        *this = *this % another;

        return *this;

    }

    BigInteger& BigInteger::operator ++ ()

    {

        *this += BigInteger("1");

        return *this;

    }

     

    BigInteger& BigInteger::operator -- ()

    {

        *this -= BigInteger("1");

        return *this;

    }

     

    /**

    * 后递增(--),用参数int来代表是后递增

    * 先调用拷贝构造函数拷贝当前对象,作为最后的返回值。然后直接增加当前对象,应

             该返回值,因为返回的是局部变量的拷贝。

    @return 已经改变的对象的引用

    */ 

    BigInteger BigInteger::operator ++(int)

        //cout<<"后递增++运算符的重载"<<endl; 

        BigInteger org(*this); 

        *this += BigInteger("1");

     

        return org

    }

    BigInteger BigInteger::operator --(int)

        //cout<<"后递增++运算符的重载"<<endl; 

        BigInteger org(*this); 

        *this -= BigInteger("1");

     

        return org

    }

    bool BigInteger::operator >= (const BigInteger& another)

    {

        if(0 == sign && 1 == another.sign)

           return true;

        else if(1 == sign && 0 == another.sign)

           return false;

        else if(0 == sign && 0 == another.sign)

        {

           if(ndigit > another.ndigit)

               return true;

           else if(ndigit < another.ndigit)

               return false;

           else

           {

               int i = 0;

               while('\0' != modulus[i])

               {

                  if(modulus[i] > another.modulus[i])

                      return true;

                  else if(modulus[i] < another.modulus[i])

                      return false;

                  i++;

               }

               return true;

           }

        }

        else

        {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           return (-a2) >= (-a1);

        }

    }

     

    bool BigInteger::operator > (const BigInteger& another)

    {

        if(*this <= another)

           return false;

        else

           return true;

    }

     

    bool BigInteger::operator <= (const BigInteger& another)

    {

        if(0 == sign && 1 == another.sign)

           return false;

        else if(1 == sign && 0 == another.sign)

           return true;

        else if(0 == sign && 0 == another.sign)

        {

           if(ndigit > another.ndigit)

               return false;

           else if(ndigit < another.ndigit)

               return true;

           else

           {

               int i = 0;

               while('\0' != modulus[i])

               {

                  if(modulus[i] > another.modulus[i])

                      return false;

                  else if(modulus[i] < another.modulus[i])

                      return true;

                  i++;

               }

               return true;

           }

        }

        else

        {

           BigInteger a1 = *this;

           BigInteger a2 = another;

           return (-a2) <= (-a1);

        }

    }

     

    bool BigInteger::operator < (const BigInteger& another)

    {

        if(*this >= another)

           return false;

        else

           return true;

    }

     

    bool BigInteger::operator == (const BigInteger& another)

    {

        if((*this >= another) && (*this <= another))

           return true;

        else

           return false;

    }

    bool BigInteger::operator != (const BigInteger& another)

    {

        if((*this > another) || (*this < another))

           return true;

        else

           return false;

    }

  • 相关阅读:
    zoj 4120Tokens on the Segments(优先队列+贪心)
    hdu1710 Binary Tree Traversals(二叉树)
    poj3494Largest Submatrix of All 1’s
    poj 2559Largest Rectangle in a Histogram(单调栈简单模板题)
    poj 2492 A Bug's Life(种类并查集)
    差分约束 + spfa + 最长路 [NOI1999] 01串
    Codeforces Round #599 D Yet Another Monster Killing Problem
    CF 1249D1
    [Gym-102346A] 偷偷偷 并查集处理图(坐标)
    [Gym-102346M] 二分答案
  • 原文地址:https://www.cnblogs.com/loongfee/p/1595665.html
Copyright © 2020-2023  润新知