无限长度整数处理,又开始搞C++了,代码复用用起来

封装一个先,还没写完,后面再改

/* 
        ###   ###
        #### ####
        #########
        ## ### ##
        ##  #  ##
        ##     ##          AaronMing 2022
       ####   ####

    超长整数处理类型

    2022-11-13  创建
    2022-11-19  增加对int的乘法计算
    2022-11-20  增加==重载
                增加对int的乘法计算的负数处理方式

 */
#include <iostream>
#include <vector>
#include <string>

using namespace std;
//定义存储在data中的数据类型
typedef unsigned long ITYPE;
//定义取模运算结果的类型
typedef unsigned long MODRT;

//超长整数处理
class CMLargeInt {
    private:
        //标记是否为负数
        bool negative = false;
        //所有数据都是逆序排放的,如123,存储为3,2,1
        vector<ITYPE> data = {};
        //将先导0清除
        void trim0() {
            if (!this->data.empty()) {
                for(vector<ITYPE>::iterator iter = this->data.end() - 1;
                    iter >= this->data.begin();
                    --iter) {
                    if (*iter == 0) {
                        this->data.erase(iter);
                    } else break;
                }
            }
        }
        //设置新数据,采用引用调用减少内存消耗
        void SetData(string & s) {
            this->data.clear(); //首先清空数据
            if (s.length() > 0) 
                this->negative = (*(s.begin()) == '-'); //首字母判断是否为负数
                for (string::iterator iter = s.end() - 1;
                    iter >= s.begin();
                    --iter
                    ){
                    //判断是否是数字字符,反向插入数据
                    if ('0' <= *iter && *iter <= '9')
                        this->data.push_back(*iter - '0');
            }
            this->trim0(); //完成后删除先导零
        }
    public:
        //构造
        CMLargeInt () {};
        //构造
        CMLargeInt (string & s) {
            this->SetData(s);
        };
        //构造
        CMLargeInt (const char* ps) {
            string s(ps);
            this->SetData(s);
            
        }
        //析构时释放data
        ~CMLargeInt() { 
            this->data.clear();
        }     
        //将和另外一个CMLargeInt
        static void add(CMLargeInt &a, CMLargeInt &b, CMLargeInt &Asum) {
            //首先清空总和的data
            Asum.data.clear();
            if (a.data.empty()) Asum.data = b.data; 
            else if (b.data.empty()) Asum.data = a.data;
            else {
                vector<ITYPE>::iterator ia = a.data.begin();
                vector<ITYPE>::iterator ib = b.data.begin();
                ITYPE t = 0;    //临时数据和
                ITYPE carry = 0; //进位
                //如果两个加数都没处理完,先进行两个加数运算                
                while ((ia != a.data.end()) && (ib != b.data.end())) {
                    t = *ia + *ib + carry;
                    carry = t / 10; //计算进位
                    t = t % 10; //计算保留值
                    Asum.data.push_back(t);                    
                    ++ia; ++ib; //将迭代器后移
                }
                //分别处理剩下的高位数
                if (ia != a.data.end()) {
                    while (ia != a.data.end())
                    {
                        t = *ia + carry;
                        carry = t / 10;
                        t = t % 10;
                        Asum.data.push_back(t);
                        ++ia;
                    }
                } else if (ib != b.data.end()) {
                    while (ib != b.data.end())
                    {
                        t = *ib + carry;
                        carry = t / 10;
                        t = t % 10;
                        Asum.data.push_back(t);
                        ++ib;
                    } 
                }
                if (carry > 0) Asum.data.push_back(carry);
            }
        }
        //返回数值的字符串
        string ToString() {
            string r = "";
            this->trim0(); //删除前导0
            if (this->data.empty()) r = "0";
            else for (vector<ITYPE>::iterator iter = this->data.begin(); 
                    iter != this->data.end();
                    ++iter
                    ) {
                    r = char(*iter + '0') + r;
            }
            if (this->negative) r = '-' + r;
            return r;
        }
        //乘以一个整数,小心指数爆炸
        void MultiByInt(int n) {
            if (!this->data.empty()) { //如果当前数据不为空
                //如果是负数则改变当前的符号,对n取整数
                if (n < 0) {
                    this->negative = !this->negative;
                    n = -n;
                }
                for (vector<ITYPE>::iterator it = this->data.begin(); it != this->data.end(); ++it) {
                    *it *= n; //分别对每一位乘以n
                }
                //进位处理
                int carry = 0; //进位
                for (int i = 0; i < this->data.size(); ++i) {
                    carry = this->data[i] / 10; //计算进位
                    if (carry) {
                        if (i == (this->data.size() - 1)) this->data.push_back(carry);
                        else this->data[i+1] += carry;
                        this->data[i] %= 10;
                    }
                }
            }
        }
        //对一个正整数取模
        MODRT ModByInt(int n) {
            return 0;
        }

        //重载赋值运算
        CMLargeInt & operator = (string & s) {
            this->SetData(s);
            return *this;
        }
        //重载赋值运算
        CMLargeInt & operator = (const char* ps) {
            string s(ps);
            this->SetData(s);
            return *this;
        } 
        CMLargeInt operator + (CMLargeInt & b) {
            CMLargeInt r;
            this->add(*this, b, r);
            return r;
        }
        CMLargeInt & operator += (CMLargeInt & b) {
            CMLargeInt r;
            this->add(*this, b, r);
            *this = r;
            return *this;
        }
        bool operator == (CMLargeInt & li) {
            bool r = true; //初始化结果成立
            if ((this->data.size() == li.data.size())
                &&
                (this->negative == li.negative)
                ) {
                if (this->data.size() > 0) {
                    vector<ITYPE>::iterator itr1 = this->data.begin();
                    vector<ITYPE>::iterator itr2 = li.data.begin();
                    while (itr1 < this->data.end())
                    {
                        if (*itr1 != *itr2) {
                            r = false; break;
                        }
                        ++itr1,++itr2;
                    }
                    
                }
            } else r = false;
            return r;
        }       
        //重载流输入输出
        friend ostream & operator << (ostream &ostre, CMLargeInt oput);       
        friend istream & operator >> (istream &istre, CMLargeInt & iput);  
};

ostream & operator << (ostream &ostre, CMLargeInt oput){
    ostre << oput.ToString();
    return ostre;
}

istream & operator >> (istream &istre, CMLargeInt & iput){
    string s;
    istre >> s;
    iput.SetData(s);
    return istre;
}

调用

#include <iostream>
#include "MLargeInt"

using namespace std;

int main() {
    CMLargeInt li1 = "1";

    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) 
        li1.MultiByInt(2);

    cout << "2^" << n << "=" << li1;

}
posted @ 2022-11-20 20:34  iamy  阅读(84)  评论(0)    收藏  举报