* 运算符重载 编程题#4:大整数的加减乘除(Coursera 程序设计与算法;重载:& operator <<, & operator >>, +, -, *, /)

来源:互联网 发布:mac切换窗口手势 编辑:程序博客网 时间:2024/06/06 01:42

编程题#4:大整数的加减乘除

来源: POJ (http://cxsjsxmooc.openjudge.cn/test/D/)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述
给出两个正整数以及四则运算操作符(+ - * /),求运算结果。

输入
第一行:正整数a,长度不超过100
第二行:四则运算符o,o是“+”,“-”,“*”,“/”中的某一个
第三行:正整数b,长度不超过100

保证输入不含多余的空格或其它字符

输出
一行:表达式“a o b”的值。

补充说明:
1. 减法结果有可能为负数
2. 除法结果向下取整
3. 输出符合日常书写习惯,不能有多余的0、空格或其它字符

样例输入
9876543210
+
9876543210

样例输出
19753086420

#include <iostream>#include <string>#include <cstdlib>#include <algorithm>  //reverse函数所需添加的头文件using namespace std;class BigInt{private:    string values;  //保存所有位上的数字    bool flag;      //true表示正数,false表示负数,0默认为正数    inline int compare(string s1, string s2){        if (s1.size() < s2.size())            return -1;        else if (s1.size() > s2.size())            return 1;        else            return s1.compare(s2);  //http://www.cplusplus.com/reference/string/string/compare/    }public:    BigInt() :values("0"), flag(true){};    BigInt(string str)  //类型转换构造函数(默认为正整数)    {        values = str;        flag = true;    }public:    friend ostream& operator << (ostream& os, const BigInt& bigInt);  //重载输出操作符    friend istream& operator>>(istream& is, BigInt& bigInt);  //输入操作符重载    BigInt operator+(const BigInt& rhs);  //加法操作重载    BigInt operator-(const BigInt& rhs);  //减法操作重载    BigInt operator*(const BigInt& rhs);  //乘法操作重载    BigInt operator/(const BigInt& rhs);  //除法操作重载};//重载流提取运算符'<<',输出一个整数****************************************************************ostream& operator << (ostream& os, const BigInt& bigInt){    if (!bigInt.flag){        os << '-';    }    os << bigInt.values;    return os;}//重载流插入运算符'>>',输入一个正整数***************************************************************istream& operator >> (istream& is, BigInt& bigInt){    string str;    is >> str;    bigInt.values = str;    bigInt.flag = true;    return is;}//加法操作重载***************************************************************************************//具体思路就是模仿手算的加法BigInt BigInt::operator+(const BigInt& rhs){    BigInt ret;                                   //ret: result    ret.flag = true;  //正整数相加恒为正数    string lvalues(values), rvalues(rhs.values);  //lvalues: left values, rvalues: right values    //处理特殊情况                                 //是在values所在的类中调用的 + 号,然后在以引用的形式调用rvalues,即rhs.values    if (lvalues == "0"){        ret.values = rvalues;        return ret;    }    if (rvalues == "0"){        ret.values = lvalues;        return ret;    }    //调整s1与s2的长度    unsigned int i, lsize, rsize;    lsize = lvalues.size();    rsize = rvalues.size();    if (lsize < rsize){        for (i = 0; i < rsize - lsize; i++)  //在lvalues左边补零        {            lvalues = "0" + lvalues;        }    }    else    {        for (i = 0; i < lsize - rsize; i++)  //在rvalues左边补零        {            rvalues = "0" + rvalues;        }    }    //处理本质情况    int n1, n2;    n2 = 0;    lsize = lvalues.size();    string res = "";    reverse(lvalues.begin(), lvalues.end());  //颠倒字符串,以方便从低位算起计算    reverse(rvalues.begin(), rvalues.end());    for (i = 0; i < lsize; i++){        n1 = ((lvalues[i] - '0') + (rvalues[i] - '0') + n2) % 10;  //n1代表当前位的值;lvalues[i] 和 '0' 都是 char 型,可以作差得到 int 型        //n1 = (lvalues[i] - '0' + rvalues[i] - '0' + n2) % 10; 这样也可以,但不直观        n2 = ((lvalues[i] - '0') + (rvalues[i] - '0') + n2) / 10;  //n2代表进位        res = res + char(n1 + '0');    }    if (n2 == 1){        res = res + "1";    }    reverse(res.begin(), res.end());    ret.values = res;    return ret;}//减法操作重载***************************************************************************************//同样是模拟手算BigInt BigInt::operator-(const BigInt& rhs){    BigInt ret;    string lvalues(values), rvalues(rhs.values);    //处理特殊情况    if (rvalues == "0"){        ret.values = lvalues;        ret.flag = true;                     //此时作差定为正数        return ret;    }    if (lvalues == "0"){        ret.values = rvalues;        ret.flag = false;                    //此时作差定为负数        return ret;    }    //调整s1与s2的长度    unsigned int i, lsize, rsize;    lsize = lvalues.size();    rsize = rvalues.size();    if (lsize < rsize){        for (i = 0; i < rsize - lsize; i++)  //在lvalues左边补零        {            lvalues = "0" + lvalues;        }    }    else    {        for (i = 0; i < lsize - rsize; i++)  //在rvalues左边补零        {            rvalues = "0" + rvalues;        }    }    //调整使‘-’号前边的数大于后边的数    int t = lvalues.compare(rvalues);  //相等返回0,str1<str2返回负数,str1>str2返回正数    if (t < 0)                         //比较规则:对两个字符串自左至右逐个字符按ASCII码值比较    {        ret.flag = false;              //此时作差定为负数        string tmp = lvalues;          //lvalues 与 rvalues 调换        lvalues = rvalues;        rvalues = tmp;    }    else if (t == 0)    {        ret.values = "0";        ret.flag = true;        return ret;    }    else    {        ret.flag = true;    }    //处理本质情况    unsigned int j;    lsize = lvalues.size();    string res = "";    reverse(lvalues.begin(), lvalues.end());   //颠倒字符串,以方便从低位算起计算    reverse(rvalues.begin(), rvalues.end());    for (i = 0; i < lsize; i++){        if (lvalues[i] < rvalues[i])           //不足,向前借一位        {            j = 1;            while (lvalues[i + j] == '0'){                lvalues[i + j] = '9';                j++;            }            lvalues[i + j] -= 1;            res = res + char(lvalues[i] + ':' - rvalues[i]);        }        else{            res = res + char(lvalues[i] - rvalues[i] + '0');        }    }    reverse(res.begin(), res.end());    res.erase(0, res.find_first_not_of('0'));  //去掉前导零    ret.values = res;    return ret;}//乘法操作重载***************************************************************************************//模拟手算BigInt BigInt::operator*(const BigInt& rhs){    BigInt ret;    string lvalues(values), rvalues(rhs.values);    //处理特殊情况    if (lvalues == "0" || rvalues == "0"){        ret.values = "0";        ret.flag = true;        return ret;    }    unsigned int lsize, rsize;    lsize = lvalues.size();    rsize = rvalues.size();    string temp;    BigInt res, itemp;    //让lvalues的长度最长    if (lvalues < rvalues){        temp = lvalues;        lvalues = rvalues;        rvalues = temp;        lsize = lvalues.size();        rsize = rvalues.size();    }    //处理本质情况    int i, j, n1, n2;    reverse(lvalues.begin(), lvalues.end());  //颠倒字符串    reverse(rvalues.begin(), rvalues.end());    for (i = 0; i < rsize; i++){        temp = "";      //注意temp每次要置回空串!!!!!!        n1 = n2 = 0;    //n1,n2也要置回0!!!!!!        for (j = 0; j < lsize; j++){            n1 = ((lvalues[j] - '0')*(rvalues[i] - '0') + n2) % 10;  //n1记录当前位置的值            n2 = ((lvalues[j] - '0')*(rvalues[i] - '0') + n2) / 10;  //n2记录进位的值            temp = temp + char(n1 + '0');        }        if (n2){            temp = temp + char(n2 + '0');        }        reverse(temp.begin(), temp.end());        for (j = 0; j < i; j++){            temp = temp + "0";        }        itemp.values = temp;        res = res + itemp;  //类和类相加才会调用 + 号重载操作符!!!!!!    }    ret = res;    return ret;}//除法操作重载***************************************************************************************BigInt BigInt::operator/(const BigInt& rhs){    BigInt ret;    string lvalues(values), rvalues(rhs.values);    string quotient;    //处理特殊情况    if (rvalues == "0"){        ret.values = "error";//输出错误        ret.flag = true;        return ret;    }    if (lvalues == "0"){        ret.values = "0";        ret.flag = true;        return ret;    }    if (compare(lvalues, rvalues) < 0){        ret.values = "0";        ret.flag = true;        return ret;    }    else if (compare(lvalues, rvalues) == 0){        ret.values = "1";        ret.flag = true;        return ret;    }    else{        //处理本质情况        string temp;        unsigned int lsize, rsize;        lsize = lvalues.size();        rsize = rvalues.size();        int i;        if (rsize > 1) temp.append(lvalues, 0, rsize - 1);        for (i = rsize - 1; i < lsize; i++){            temp = temp + lvalues[i];            //试商            for (char c = '9'; c >= '0'; c--){                BigInt t = (BigInt)rvalues * (BigInt)string(1, c);  //string( size_type length, char ch ); 以length为长度的ch的拷贝(即length个ch)                 BigInt s = (BigInt)temp - t;                if (s.flag == true){                    temp = s.values;                    quotient = quotient + c;                    break;                }            }        }    }    //去除前导零    quotient.erase(0, quotient.find_first_not_of('0'));  //http://www.cplusplus.com/reference/string/string/find_first_not_of/?kw=string%3A%3Afind_first_not_of    ret.values = quotient;                               //string::erase http://www.cplusplus.com/reference/string/string/erase/?kw=string%3A%3Aerase    ret.flag = true;    return ret;}int main(){    BigInt a, b, result;    char op;    cin >> a >> op >> b;    switch (op)    {    case '+':result = a + b; break;    case '-':result = a - b; break;    case '*':result = a * b; break;    case '/':result = a / b; break;    default:break;    }    cout << result << endl;    return 0;}/*测试数据:1.741269586512*9845624786542.48789151687984156*564871123467863.56765156165465786156467/546578154547824.8465156478654165468421-156468781154878543122345675.48951487894146576543215646+51231231657845123132156866.87894123467984512789/5684答案如下:1.7298262214470804063148482.27559582927035448314667455226163.10385551574.-156384129590092001467661465.540746110599310888564313326.15463427774100019*/

本文转载自:http://blog.csdn.net/nnnnnnnnnnnny/article/details/50335615

其它解法参考:
http://blog.csdn.net/nk_test/article/details/48912763