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

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

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;
	else
		return 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 < s2
		return "-" + sub_int(s2, s1);

	if (t == 0)
		return "0";

	//处理本质情况:s1 > s2
	string 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;
		else
			return residue;
	}
	if (s1 == "0")
	{
		quotient = residue = "0";
		if (flag == 1)
			return quotient;
		else
			return 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";
		else
			residue = "-" + 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值