c++ 程序设计 wee4 作业 大整数四则运算

来源:互联网 发布:mac系统能玩的网络游戏 编辑:程序博客网 时间:2024/05/16 10:37

这个没时间写了. 但是为了完整性, 先把转载别人的代码.

http://blog.csdn.net/zhangxiangdavaid/article/details/46438865


我自己终于改好了, 虽然大部分代码和下面很相似, 但是

经验如下:

(1) 封装, 写好test 程序先, 再逐一测试代码


(2) string有很多有用函数: 

(a) erase

 string& erase (size_t pos = 0, size_t len = npos);

(b) append

string& append (const string& str, size_t subpos, size_t sublen);

(c) empty

bool empty() const;

(d) compare

int compare (const string& str) const;

#include<iostream>#include<string>using namespace std;string add_int(string, string);  string sub_int(string, string);  string mul_int(string, string);  string div_int(string, string);  class Lint{    private:        string s;    public:        Lint(string s1):s(s1){}        friend Lint operator+(const Lint &a, const Lint &b);        friend Lint operator-(const Lint &a, const Lint &b);        friend Lint operator*(const Lint &a, const Lint &b);        friend Lint operator/(const Lint &a, const Lint &b);        friend ostream& operator<<(ostream& os, const Lint &a);};ostream& operator<<(ostream &os, const Lint &a){    os << a.s;    return os;}Lint operator+(const Lint &a, const Lint &b){    string result;    result = add_int(a.s,b.s);    return Lint(result);}Lint operator-(const Lint &a, const Lint &b){    string result;    result = sub_int(a.s, b.s);    return Lint(result);}Lint operator*(const Lint &a, const Lint &b){    string result;    result = mul_int(a.s,b.s);    return Lint(result);}Lint operator/(const Lint &a, const Lint &b){    string result;    result = div_int(a.s,b.s);    return Lint(result);}int main(){    string a, op, b;    cin >> a>>op>>b;    Lint x(a);    Lint y(b);    switch(op.c_str()[0])    {        case '+':            cout << x+y<<endl;            break;        case '-':            cout << x-y<<endl;            break;        case '*':            cout << x*y<<endl;            break;        case '/':            cout<<x/y<<endl;            break;    }    return 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);  }/* * basic case: * "123" + "456" * * other case: * (1)"-123"+"456" * (2)"-123"+"-456" * (3)"-123"+"-456" */string add_int(string s1,string s2){    if(s1 == "0")        return s2;    if(s2 == "0")        return s1;    if(s1[0] == '-')    {        if(s2[0] == '-')            return "-"+add_int(s1.erase(0,1),s2.erase(0,1)); //case(3)        else            return sub_int(s2,s1.erase(0,1)); //case(1)    }    if(s2[0] == '-')        return sub_int(s1,s2.erase(0,1));    //处理本质情况    string::size_type i,size1,size2;    size1 = s1.size();    size2 = s2.size();    if( size1<size2)    {        for(int i = 0;i<size2-size1;i++)            s1 = "0"+s1;    }    else if(size1 > size2)    {        for(int i = 0;i<size1-size2;i++)            s2 = "0"+s2;    }    int  n1,n2;    n2 = 0;    size1 = s1.size();    string res;    for (int i = size1-1;i>=0;i--)    {        n1 = (s1[i] - '0'+s2[i] - '0'+n2) %10; //当前位置的计算结果        n2 = (s1[i] - '0'+s2[i] - '0'+n2)/10; //进位        res = char(n1+'0')+res;    }    if(n2 == 1)        res = "1"+res;        return res;}/* *basic: "1234" - "234" *需要转化情况 (1) "234" - "1234" (2)"-234" - "1234" (3)"-234" - ""-1234 (4) "234" - "-1234" */string sub_int(string s1,string s2){    if(s2 == "0")        return s1;    if(s1 == "0")    {        if(s2[0] == '-')            return s2.erase(0,1);        return "-"+s2;    }    if(s1[0] == '-')    {        if(s2[0] == '-')            return sub_int(s2.erase(0,1),s1.erase(0,1)); //(3)        else            return "-"+add_int(s1.erase(0,1),s2); //(2)    }    if(s2[0] == '-')    {        return add_int(s1,s2.erase(0,1));    }    string::size_type i, size1,size2;    size1 = s1.size();    size2 = s2.size();    if(size1<size2)    {        for(int i = 0; i<size2-size1;i++)            s1 = "0"+s1;    }    else if(size2<size1)    {        for (int i = 0; i<size1-size2;i++)            s2 = "0"+s2;    }    int t = s1.compare(s2);    if (t < 0)        return "-" + sub_int(s2,s1);    if (t == 0)        return "0";    //基本情况    size1 = s1.size();    int cut = 0;    string res;    for(int i = size1-1;i>=0;i--)    {        if(s1[i]>=s2[i]+cut)        {            res = char('0'+s1[i]-s2[i]-cut)+res;            cut = 0;        }        else        {            res = char('0'+s1[i]-s2[i]+10-cut)+res;            cut = 1;        }    }    while(res[0]=='0')    {        res.erase(0,1);    }    return res;}string mul_int(string s1,string s2){    if(s1 == "0" || s2 == "0")    {        return "0";    }    int sign = 1;    if( s1[0] == '-')    {        sign *= -1;        s1.erase(0,1);    }    if(s2[0] == '-')    {        sign *= -1;        s2.erase(0,1);    }    string::size_type size1,size2;    size1 = s1.size();    size2 = s2.size();    if(size1<size2)    {        for(int i = 0; i<size2-size1;i++)            s1 = "0"+s1;    }    else    {        for(int i = 0;i<size1-size2;i++)            s2 = "0" + s2;    }    string res = "0";    size1 = s1.size();    for(int i = size1-1;i>=0;i--)    {        string cur;        if(size1-1>i)        {            cur = string(size1 -1 - i,'0');        }        int n1,n2;        n2 = 0;        for(int j = size1 - 1;j>=0;j--)        {            n1 = ((s2[j]-'0')*(s1[i]-'0') + n2)%10;            n2 = ((s2[j]-'0')*(s1[i]-'0') + n2)/10;            cur = char('0'+n1) + cur;           }        if(n2!=0)            cur = char('0'+n2)+cur;        while(cur[0] == '0')            cur.erase(0,1);        if(cur.empty())            cur = "0";        res = add_int(res,cur);    }    return res;}string div_int(string s1, string s2){    string quotient,residue;    if(s2 == "0")    {        quotient = "error";        return quotient;    }    if(s1 == "0")        return "0";    int sign1,sign2;    sign1 = sign2 = 1;    if(s1[0] == '-')    {        sign1 *= -1;        sign2 = -1;        s1.erase(0,1);    }    if(s2[0] == '-')    {        sign1 *= -1;        s2.erase(0,1);    }    if(compare(s1,s2)<0)    {        quotient = "0";        residue = s1;    }    else if(compare(s1,s2)==0)    {        quotient = "1";        residue = "0";    }    else    {        string temp;        string::size_type size1,size2;        size1 = s1.size();        size2 = s2.size();        int i;        if(size2>1) temp.append(s1,0,size2-1);//初始化        for(int i = size2-1;i<size1;i++)        {            temp = temp+s1[i];            for(char c = '9';c>='0';c--)            {                string t = mul_int(s2,string(1,c));                string s = sub_int(temp,t);                //cout <<c<< t << " "<<s<<endl;                if(s == "0"|| s[0] != '-')                {                    temp = s;                    quotient = quotient + c;                 //   cout << c <<endl;                    break;                }            }        }        residue = temp;        quotient.erase(0,quotient.find_first_not_of('0'));        residue.erase(0,residue.find_first_not_of('0'));        if(sign1 == -1)        {            quotient = "-"+quotient;        }        return quotient;    }}


#include <iostream>#include <string>using namespace std;//大整数的加减乘除string add_int(string, string);string sub_int(string, string);string mul_int(string, string);string div_int(string, string);string mod_int(string, string);string divide_int(string, string, int);inline int compare(string s1, string s2){if (s1.size() < s2.size())return -1;else if (s1.size() > s2.size())return 1;elsereturn s1.compare(s2);}/*大整数加法本质上只处理:两个正数相加,如 "123" + "234"其它情况需转化1. 正加负 => "123" + "-234"  = "123" - "234" 转化为减法2. 负加正 => "-234" + "123"  = "123" - "234"3. 负加负 => "-123" + "-234" = -("123" + "234")*/string add_int(string s1, string s2){if (s1 == "0")return s2;if (s2 == "0")return s1;if (s1[0] == '-'){if (s2[0] == '-'){return "-" + add_int(s1.erase(0, 1), s2.erase(0, 1));  //情况三}else{return sub_int(s2, s1.erase(0, 1));  //情况二}}if (s2[0] == '-'){return sub_int(s1, s2.erase(0, 1));  //情况一}//处理本质情况string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++)   //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++)   //在s2左边补零s2 = "0" + s2;}int n1, n2;n2 = 0;size1 = s1.size();size2 = s2.size();string res;for (i = size1 - 1; i != 0; i--)   //从最低位加起{n1 = (s1[i] - '0' + s2[i] - '0' + n2) % 10;  //n1代表当前位的值n2 = (s1[i] - '0' + s2[i] - '0' + n2) / 10;  //n2代表进位res = char(n1 + '0') + res;}/*上述循环不能处理第0位的原因在于i的类型是string::size_type,它是非负类型*///对于第0位单独处理n1 = (s1[0] - '0' + s2[0] - '0' + n2) % 10;n2 = (s1[0] - '0' + s2[0] - '0' + n2) / 10;res = char(n1 + '0') + res;if (n2 == 1)res = "1" + res;return res;}/*大整数减法本质上只处理:两整数相减,并且是一大减一小:"1234" - "234"其它情况需转化1. 小正减大正 => "234" - "1234" = -("1234" - "234")2. 正减负 => "1234" - "-234" = "1234" + "234"3. 负减正 => "-1234" - "234" = -("1234" + "234")4. 负减负 => "-1234" - "-234" = "234" - "1234" = -("1234" - "234")*/string sub_int(string s1, string s2){if (s2 == "0")return s1;if (s1 == "0"){if (s2[0] == '-')return s2.erase(0, 1);return "-" + s2;}if (s1[0] == '-'){if (s2[0] == '-'){return sub_int(s2.erase(0, 1), s1.erase(0, 1));   //情况四}return "-" + add_int(s1.erase(0, 1), s2);   //情况三}if (s2[0] == '-')return add_int(s1, s2.erase(0, 1));  //情况二//调整s1与s2的长度string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++)   //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++)   //在s2左边补零s2 = "0" + s2;}int t = s1.compare(s2);if (t < 0)   //s1与s2的size相同,但 s1 < s2return "-" + sub_int(s2, s1);if (t == 0)return "0";//处理本质情况:s1 > s2string res;string::size_type j;for (i = s1.size() - 1; i != 0; i--){if (s1[i] < s2[i])   //不足,需向前借一位{j = 1;while (s1[i - j] == '0'){s1[i - j] = '9';j++;}s1[i - j] -= 1;res = char(s1[i] + ':' - s2[i]) + res;}else{res = char(s1[i] - s2[i] + '0') + res;}}res = char(s1[0] - s2[0] + '0') + res;//去掉前导零res.erase(0, res.find_first_not_of('0'));return res;}string mul_int(string s1, string s2){if (s1 == "0" || s2 == "0")return "0";//sign是符号位int sign = 1;if (s1[0] == '-'){sign *= -1;s1.erase(0, 1);}if (s2[0] == '-'){sign *= -1;s2.erase(0, 1);}string::size_type size1, size2;string res, temp;size1 = s1.size();size2 = s2.size();//让s1的长度最长if (size1 < size2){temp = s1;s1 = s2;s2 = temp;size1 = s1.size();size2 = s2.size();}int i, j, n1, n2, n3, t;for (i = size2 - 1; i >= 0; i--){temp = "";n1 = n2 = n3 = 0;for (j = 0; j < size2 - 1 - i; j++) temp = "0" + temp;n3 = s2[i] - '0';for (j = size1 - 1; j >= 0; j--){t = (n3*(s1[j] - '0') + n2);n1 = t % 10;  //n1记录当前位置的值n2 = t / 10;  //n2记录进位的值temp = char(n1 + '0') + temp;}if (n2)temp = char(n2 + '0') + temp;res = add_int(res, temp);}if (sign == -1)return "-" + res;return res;}string divide_int(string s1, string s2, int flag)  //flag=1,返回商;flag=0,返回余数{string quotient, residue;if (s2 == "0"){quotient = residue = "error";if (flag == 1)return quotient;elsereturn residue;}if (s1 == "0"){quotient = residue = "0";if (flag == 1)return quotient;elsereturn residue;}//sign1是商的符号,sign2是余数的符号int sign1, sign2;sign1 = sign2 = 1;if (s1[0] == '-'){sign1 *= -1;sign2 = -1;s1.erase(0, 1);}if (s2[0] == '-'){sign1 *= -1;s2.erase(0, 1);}if (compare(s1, s2) < 0){quotient = "0";residue = s1;}else if (compare(s1, s2) == 0){quotient = "1";residue = "0";}else{string temp;string::size_type size1, size2;size1 = s1.size();size2 = s2.size();int i;if (size2 > 1) temp.append(s1, 0, size2 - 1);for (i = size2 - 1; i < size1; i++){temp = temp + s1[i];//试商for (char c = '9'; c >= '0' ; c--){string t = mul_int(s2, string(1, c));string s = sub_int(temp, t);if (s == "0" || s[0] != '-'){temp = s;quotient = quotient + c;break;}}}residue = temp;}//去除前导零quotient.erase(0, quotient.find_first_not_of('0'));residue.erase(0, residue.find_first_not_of('0'));if (sign1 == -1){quotient = "-" + quotient;}if (sign2 == -1){if (residue.empty())residue = "0";elseresidue = "-" + residue;}if (flag == 1) return quotient;else return residue;}string div_int(string s1, string s2){return divide_int(s1, s2, 1);}string mod_int(string s1, string s2){return divide_int(s1, s2, 0);}int main(void){string s1, s2;char op;while (cin >> s1 >> op >> s2){switch (op){case '+':cout << add_int(s1, s2) << endl; break;case '-':cout << sub_int(s1, s2) << endl; break;case '*':cout << mul_int(s1, s2) << endl; break;case '/':cout << div_int(s1, s2) << endl; break;case '%':cout << mod_int(s1, s2) << endl; break;default:cout << "The operator is error!" << endl; break;}}return 0;}


0 0
原创粉丝点击