• 大整数类 模板


    自己写的大整数模板,已经升级到V2.0

    功能:

    计算大整数加减乘数取模运算,支持无限位数,支持正负数输入输出及运算,支持判断两个大整数的大小

    保障:

    1.VC++2013,GCC4.7.3运行测试通过

    2.学校OJ加减乘除取模均AC

    //BigInt V2.0
    //By KunSoft
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <deque>
    #include <iterator>
    #include <algorithm>
    using namespace std;
    typedef long long LLT;
    
    class BigInt
    {
    public:
    	BigInt() :negative(false) {}
    	BigInt(const LLT);
    	BigInt(const char*);
    	BigInt(const string);
    	BigInt(const BigInt & x);
    	BigInt & operator = (const BigInt &);
    	friend istream & operator >> (istream &, BigInt &);
    	friend ostream & operator << (ostream &, BigInt);
    	BigInt operator + (const BigInt &) const;
    	BigInt operator - (const BigInt &) const;
    	BigInt operator * (const BigInt &) const;
    	BigInt operator / (const LLT &) const;
    	LLT operator % (const LLT &) const;
    	bool operator > (const BigInt &) const;
    	bool operator == (const BigInt &) const;
    	bool operator >= (const BigInt &) const;
    	friend BigInt abs(const BigInt &);
    	BigInt operator - () const;
    private:
    	deque<int> num;
    	bool negative;
    };
    
    BigInt::BigInt(const LLT x){
    	LLT t = abs(x);
    	negative = x >= 0 ? true : false;
    	while (t > 0){
    		num.push_back(t % 10);
    		t = t / 10;
    	}
    }
    BigInt::BigInt(const char* str){
    	unsigned i = str[0] == '-' ? 1 : 0;
    	this->negative = str[0] == '-' ? true : false;
    	for (; i < strlen(str); ++i) num.push_back(str[i] - '0');
    }
    BigInt::BigInt(const string str){
    	unsigned i = str[0] == '-' ? 1 : 0;
    	this->negative = str[0] == '-' ? true : false;
    	for (; i < str.size(); ++i) num.push_back(str[i] - '0');
    }
    BigInt::BigInt(const BigInt &x){
    	negative = x.negative;
    	num = x.num;
    }
    BigInt & BigInt::operator = (const BigInt &x){
    	negative = x.negative;
    	num = x.num;
    	return (*this);
    }
    istream & operator >> (istream &is, BigInt & x){
    	string str; is >> str;
    	x = str;
    	return is;
    }
    ostream & operator << (ostream &os, BigInt x){
    	if (x.negative) os << '-';
    	for (unsigned i = 0; i != x.num.size(); ++i)
    		os << x.num[i];
    	return os;
    }
    bool BigInt::operator > (const BigInt & rhs) const {
    	BigInt x = (*this), y = rhs;
    	if (!x.negative && y.negative) return true;
    	if (x.negative && !y.negative) return false;
    	if (x.negative && y.negative) swap(x, y);
    	if (x.num.size() > y.num.size()) return true;
    	if (x.num.size() < y.num.size()) return false;
    	for (unsigned i = 0; i != x.num.size(); ++i) {
    		if (x.num[i] > y.num[i]) return true;
    		if (x.num[i] < y.num[i]) return false;
    	}
    	return false;
    }
    bool BigInt::operator == (const BigInt & rhs) const {
    	return negative == rhs.negative && num == rhs.num;
    }
    bool BigInt::operator >= (const BigInt & rhs) const {
    	return *this > rhs || *this == rhs;
    }
    BigInt abs(const BigInt & rhs){
    	BigInt res;
    	res.negative = false;
    	res.num = rhs.num;
    	return res;
    }
    BigInt BigInt::operator - () const {
    	BigInt ret = *this; ret.negative = !ret.negative;
    	return ret;
    }
    BigInt BigInt::operator + (const BigInt & y) const {
    	if (!this->negative && y.negative) return *this - abs(y);
    	if (this->negative && !y.negative) return y - abs(*this);
    	if (this->negative && y.negative) return -(abs(*this) + abs(y));
    	BigInt x = *this, res;
    	int temp = 0;
    	for (int i = x.num.size() - 1, j = y.num.size() - 1; i >= 0 || j >= 0; --i, --j) {
    		int a = i < 0 ? 0 : x.num[i];
    		int b = j < 0 ? 0 : y.num[j];
    		res.num.push_front((a + b + temp) % 10);
    		temp = (a + b + temp) / 10;
    	}
    	if (temp != 0) res.num.push_front(temp);
    	return res;
    }
    BigInt BigInt::operator * (const BigInt & y) const {
    	deque<int> a, b, res;
    	copy(this->num.begin(), this->num.end(), front_inserter(a));
    	copy(y.num.begin(), y.num.end(), front_inserter(b));
    	res.resize(a.size() + b.size() + 5);
    	for (unsigned i = 0; i < a.size(); ++i) for (unsigned j = 0; j < b.size(); ++j)
    		res[i + j] += a[i] * b[j];
    	for (unsigned i = 0; i < res.size() - 1; ++i){
    		res[i + 1] += res[i] / 10;
    		res[i] %= 10;
    	}
    	while (res.size() >= 2 && res.back() == 0)
    		res.pop_back();
    	reverse(res.begin(), res.end());
    	BigInt ret; ret.negative = this->negative ^ y.negative; ret.num = res;
    	return ret;
    }
    BigInt BigInt::operator - (const BigInt & y) const {
    	if (!this->negative && y.negative) return *this + abs(y);
    	if (this->negative && !y.negative) return -(abs(*this) + y);
    	if (this->negative && y.negative) return abs(y) - abs(*this);
    	deque<int> a, b, res; BigInt ret;
    	copy(this->num.begin(), this->num.end(), front_inserter(a));
    	copy(y.num.begin(), y.num.end(), front_inserter(b));
    	if (y > *this) swap(a, b), ret.negative = true;
    	res.resize(max(a.size(), b.size()) + 5);
    	for (unsigned i = 0, j = 0; i < a.size() || j < b.size(); ++i, ++j){
    		int m = i < a.size() ? a[i] : 0;
    		int n = j < b.size() ? b[j] : 0;
    		res[i] = m - n;
    	}
    	for (unsigned i = 0; i < res.size() - 1; ++i) if (res[i] < 0) {
    		res[i] += 10;
    		--res[i + 1];
    	}
    	while (res.size() >= 2 && res.back() == 0)
    		res.pop_back();
    	reverse(res.begin(), res.end()); ret.num = res;
    	return ret;
    }
    BigInt BigInt::operator / (const LLT & y) const {
    	LLT temp = 0;
    	BigInt x = (*this), res;
    	for (unsigned i = 0; i < x.num.size(); ++i){
    		temp = temp * 10 + x.num[i];
    		res.num.push_back((int)(temp / y));
    		temp %= y;
    	}
    	while (res.num.size() >= 2 && res.num.front() == 0)
    		res.num.pop_front();
    	return res;
    }
    LLT BigInt::operator % (const LLT & y) const {
    	LLT res = 0;
    	for (unsigned i = 0; i < this->num.size(); ++i)
    		res = (res * 10 + this->num[i]) % y;
    	return res;
    }
    
    
    
    
    
    
    
    
    int main()
    {
    	BigInt a, b;
    	while (cin >> a >> b)
    		cout << a + b << endl;
    	return  0;
    }
    



    下面是老版的V1.0版本提供参考,使用数组实现,速度会快一些。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <algorithm>
    #define MAXN 1024
    using namespace std;
    
    class BigInt
    {
    private:
        int num[MAXN];
        int len;
        int flag;
    public:
        BigInt()
        {
            memset(num, 0, sizeof(num));
            len = 0;
            flag = 1;
        };
        BigInt(const int);
        BigInt(const char*);
        BigInt(const string);
        BigInt(const BigInt &x);
        BigInt &operator = (const BigInt &);
    
        friend istream &operator >> (istream &, BigInt &);
        friend ostream &operator << (ostream &, BigInt &);
    
        BigInt operator + (const BigInt &);
        BigInt operator - (const BigInt &);
        BigInt operator * (const BigInt &);
        BigInt operator / (const long long int &);
        long long int operator % (const long long int &);
        bool operator > (const BigInt &);
    
        friend BigInt rev(const BigInt &x);
    };
    
    //将一个int类型的变量转化为BigInt类型
    BigInt::BigInt(const int x)
    {
        memset(num, 0, sizeof(num));
        len = 0;
        int t;
        if(x < 0)
        {
            t = -x;
            flag = -1;
        }
        else
            t = x;
        while (t > 0)
        {
            num[len++] = t % 10;
            t = t / 10;
        }
    }
    
    //将一个C风格字符串的变量转化为BigInt类型
    BigInt::BigInt(const char* str)
    {
        memset(num, 0, sizeof(num));
        len = strlen(str);
        for (int i = 0; i < len; i++)
        {
            num[i] = str[i] - '0';
        }
    }
    
    //将一个string字符串的变量转化为BigInt类型
    BigInt::BigInt(const string str)
    {
        string temp(str);
        memset(num, 0, sizeof(num));
        len = temp.size();
        int cnt = 0;
        for (string::iterator i = temp.begin(); i != temp.end(); i++)
            num[cnt++] = *i - '0';
    }
    
    //拷贝BigInt对象
    BigInt::BigInt(const BigInt &x)
    {
        len = x.len;
        flag = x.flag;
        memset(num, 0, sizeof(num));
        for (int i = 0; i < len; i++)
            num[i] = x.num[i];
    }
    
    //重载赋值运算符
    BigInt & BigInt::operator = (const BigInt &x)
    {
        len = x.len;
        flag = x.flag;
        memset(num, 0, sizeof(num));
        for (int i = 0; i < len; i++)
            num[i] = x.num[i];
        return (*this);
    }
    
    //重载输入运算符
    istream &operator >> (istream &is, BigInt &x)
    {
        string temp;
        is >> temp;
        memset(x.num, 0, sizeof(x.num));
        x.len = temp.size();
        int cnt = 0;
        for (string::iterator i = temp.begin(); i != temp.end(); i++)
            x.num[cnt++] = *i - '0';
        return is;
    }
    
    //重载输出运算符
    ostream &operator << (ostream &os, BigInt &x)
    {
        if(x.flag == -1)
            printf("-");
        for (int i = 0; i < x.len; i++)
            printf("%d", x.num[i]);
        return os;
    }
    
    //获取翻转BigInt后的BigInt
    BigInt rev(const BigInt &x)
    {
        BigInt res;
        res.len = x.len;
        res.flag = x.flag;
        memset(res.num, 0, sizeof(res.num));
        for(int i=0; i<res.len; i++)
            res.num[res.len-1-i] = x.num[i];
        return res;
    }
    
    //判断两个BigInt的大小
    bool BigInt::operator > (const BigInt &y)
    {
        BigInt x = (*this);
        if(x.len > y.len)
            return true;
        else if(x.len < y.len)
            return false;
        else if(x.len == y.len)
        {
            for(int i=0; i<x.len; i++)
            {
                if(x.num[i] > y.num[i])
                    return true;
                else if(x.num[i] < y.num[i])
                    return false;
            }
            return false;
        }
    }
    
    //两个BigInt之间的加法运算
    BigInt BigInt::operator + (const BigInt &y)
    {
        BigInt x(*this);
        BigInt res;
        int i, j;
        int cnt = 0, temp = 0;
    
        for (i = x.len - 1, j = y.len - 1; i >= 0 || j >= 0; i--, j--)
        {
            int a = i < 0 ? 0 : x.num[i];
            int b = j < 0 ? 0 : y.num[j];
            res.num[cnt++] = (a + b + temp) % 10;
            temp = (a + b + temp) / 10;
        }
        if (temp != 0)
            res.num[cnt++] = temp;
        res.len = cnt;
    
        for (int i = 0; i < (res.len / 2); i++)
        {
            int t = res.num[i];
            res.num[i] = res.num[res.len - 1 - i];
            res.num[res.len - 1 - i] = t;
        }
        return res;
    }
    
    //两个BigInt之间的乘法运算
    BigInt BigInt::operator * (const BigInt &y)
    {
        BigInt a, b, res;
        BigInt ret;
        a = rev(*this);
        b = rev(y);
    
        for(int i=0; i<a.len; i++)
            for(int j=0; j<b.len; j++)
                res.num[i+j] += a.num[i] * b.num[j];
    
        for(int i=0; i<MAXN-1; i++)
        {
            res.num[i+1] += res.num[i]/10;
            res.num[i] = res.num[i]%10;
        }
    
        for(int i = MAXN-1; i>=0; --i)
        {
            if(res.num[i]!=0)
            {
                res.len = i + 1;
                break;
            }
        }
    
        if(res.len==0)
        {
            res.len = 1;
            res.num[0] = 0;
        }
    
        ret = rev(res);
        return ret;
    }
    
    //两个BigInt之间的减法运算
    BigInt BigInt::operator - (const BigInt &y)
    {
        BigInt a = rev(*this), b = rev(y);
        BigInt res, ret;
    
        if(b > a)
        {
            swap(a, b);
            res.flag = -1;
        }
    
        for(int i=0, j=0; i<a.len || j<b.len; i++, j++)
        {
            int m = i<a.len ? a.num[i] : 0;
            int n = j<b.len ? b.num[j] : 0;
            res.num[i] = m - n;
        }
    
        for(int i=0; i<MAXN-1; i++)
        {
            if(res.num[i]<0)
            {
                res.num[i] += 10;
                res.num[i+1]--;
            }
        }
    
        for(int i = MAXN-1; i>=0; --i)
        {
            if(res.num[i]!=0)
            {
                res.len = i + 1;
                break;
            }
        }
    
        if(res.len==0)
        {
            res.len = 1;
            res.num[0] = 0;
        }
    
        ret = rev(res);
        return ret;
    }
    
    //BigInt除以一个长整形运算
    BigInt BigInt::operator / (const long long int &y)
    {
        long long int temp = 0;
        BigInt x = (*this);
        BigInt res;
        for(int i=0; i<len; i++)
        {
            temp = temp*10 + x.num[i];
            res.num[i] = temp / y;
            temp = temp % y;
        }
    
        //去前导0
        int cnt = 0;
        for(int i = 0; i<MAXN; ++i)
        {
            if(res.num[i]!=0)
            {
                cnt = i;
                break;
            }
        }
        for(int i = cnt; i<MAXN; ++i)
        {
            int t = res.num[i];
            res.num[i] = res.num[i-cnt];
            res.num[i-cnt] = t;
        }
    
        res.len = x.len - cnt;
    
        return res;
    }
    
    //BigInt对一个长整形做取余运算
    long long int BigInt::operator % (const long long int &y)
    {
        long long int temp = 0;
        BigInt x = (*this);
        BigInt res;
        for(int i=0; i<len; i++)
        {
            temp = temp*10 + x.num[i];
            res.num[i] = temp / y;
            temp = temp % y;
        }
        return temp;
    }
    
    
    
    
    
    
    
    
    int main()
    {
        return  0;
    }
    


     

  • 相关阅读:
    APIO dispatching
    奶牛抗议
    擦弹
    逃跑
    [Hnoi2016]网络
    [Ahoi2005]LANE 航线规划
    素数密度_NOI导刊2011提高(04)
    P2939 [USACO09FEB]改造路Revamping Trails(分层图最短路)
    洛谷P3396 哈希冲突(分块)
    洛谷P4332 [SHOI2014]三叉神经树(LCT)
  • 原文地址:https://www.cnblogs.com/kunsoft/p/5312800.html
Copyright © 2020-2023  润新知