大数加减法

该博客详细介绍了如何使用C++实现大数的加法和减法操作。通过处理正数和符号,将减法转换为加法,并使用字符串比较确定数值大小。大数加法通过从后往前逐位相加,处理进位;大数减法则通过确定较大数和较小数,进行减法运算,处理借位。代码实现清晰,适用于理解大数运算原理。
摘要由CSDN通过智能技术生成

处理加减法的逻辑都是处理正数,提前把符号问题处理好,然后做两个正数的加减法

做减法时,直接用字符串比较的方法,就能选出数值较大的大数,然后用大数减小数,最后添加负号即可

#include <iostream>
#include <string>
#include <algorithm>//泛型算法 

using namespace std;

//编程题目:请实现以下类的方法,完成大数的加减法
class BigInt{
public:
	BigInt(string str) {
		sign = (str[0] == '-') ? '-' : '+';
		if (sign == '-') {
			str_num = string(str.begin() + 1, str.end());
		}
		else {
			str_num = str;
		}
	}

private:
	string str_num;  //存储不带符号的字符串
	char sign;

	friend ostream& operator<<(ostream& out, const BigInt& src);
	friend BigInt operator+(const BigInt& lhs, const BigInt& rhs);
	friend BigInt operator-(const BigInt& lhs, const BigInt& rhs);
};

//打印函数
ostream& operator<<(ostream& out, const BigInt& src){
	if (src.sign == '-') {
		out << '-';
	}
	out << src.str_num;
	return out;
}

//大数加法
BigInt operator+(const BigInt& lhs, const BigInt& rhs){
	string result;//存储计算的结果 
	bool carry = false;//需不需要考虑进位 
	string num_l = lhs.str_num;
	string num_r = rhs.str_num;
	bool add_minus = false;

	if (lhs.sign == '-' && rhs.sign == '-') {
		// 两个负数相加
		add_minus = true;
	}
	else if (lhs.sign == '-') {
		// 只有lhs是负数
		return BigInt(num_r) - BigInt(num_l);
	}
	else if (rhs.sign == '-') {
		// 只有rhs是负数
		return BigInt(num_l) - BigInt(num_r);
	}

	/*
	遍历字符串l,r,从后往前遍历
	同位置的数字相加, 进位 flag  存入一个结果当中 string result
	同时完成
	某个字符串先完成   都要考虑进位
	*/
	
	int i = num_l.length() - 1; //  
	int j = num_r.length() - 1; //有效字符的长度 

	//从后往前遍历,从个位加
	for (; i >= 0 && j >= 0; --i, --j){
		int ret = num_l[i] - '0' + num_r[j] - '0';
		if (carry){
			// 有进位 
			ret += 1;
			carry = false;
		}

		if (ret >= 10){
			ret %= 10;//取余数 13就是取3 
			carry = true;
		}
		result.push_back(ret + '0');//尾部添加,从个位开始计算 
	}

	//i j
	//第一个字符串还没完
	if (i >= 0){
		while (i >= 0){
			int ret = num_l[i] - '0';
			if (carry){
				ret += 1;
				carry = false;
			}

			if (ret >= 10){
				ret %= 10;
				carry = true;
			}
			result.push_back(ret + '0');
			i--;
		}
	}
	else if (j >= 0) {
		//第二个字符串还没完
		while (j >= 0){
			int ret = num_r[j] - '0';
			if (carry){
				ret += 1;
				carry = false;
			}

			if (ret >= 10){
				ret %= 10;
				carry = true;
			}
			result.push_back(ret + '0');
			j--;
		}
	}

	//进位 
	if (carry){
		result.push_back('1');
	}
	if (add_minus) {
		result.push_back('-');
	}
	reverse(result.begin(), result.end());//翻转字符串 
	return result;//return BigInt(result)
}

//大数减法
BigInt operator-(const BigInt& lhs, const BigInt& rhs){
	string num_l = lhs.str_num;
	string num_r = rhs.str_num;

	if (lhs.sign == '-' && rhs.sign == '-') {
		// 两个负数相减
		return BigInt(num_r) - BigInt(num_l);
	}
	if (lhs.sign == '-') {
		// 只有lhs是负数
		return BigInt("0") - (BigInt(num_l) + BigInt(num_r));
	}
	if (rhs.sign == '-') {
		// 只有rhs是负数
		return BigInt(num_l) + BigInt(num_r);
	}

	/*
	找大的字符串左减数,小的左被减数
	遍历两个字符串,减法,借位(bool flag), string result存下来
	*/
	string result;
	bool borrow = false;  // 借位 
	bool minor = false;   // 最终的结果是否输出负号 

	string maxStr = num_l;
	string minStr = num_r;
	//确定大小字符串
	if (maxStr.length() < minStr.length()){
		// lhs长度小于rhs
		maxStr = num_r;
		minStr = num_l;
		minor = true;//结果要添加负号 
	}else if (maxStr.length() == minStr.length()){
		//长度相等
		if (maxStr < minStr) {
			//string类重载<,实现字符串比较大小
			maxStr = num_r;
			minStr = num_l;
			minor = true;
		}
		else if (maxStr == minStr){
			// 长度相等,内容也相等,说明两个字符串相等
			return string("0");
		}
	}

	int i = maxStr.length() - 1;
	int j = minStr.length() - 1;

	for (; i >= 0 && j >= 0; --i, --j)//从后向前,个位开始减起 
	{
		int ret = maxStr[i] - minStr[j];
		if (borrow)//借位了 
		{
			ret -= 1;
			borrow = false;
		}

		if (ret < 0)
		{
			ret += 10;
			borrow = true;
		}
		result.push_back(ret + '0');
	}

	while (i >= 0)
	{
		int ret = maxStr[i] - '0';
		if (borrow)
		{
			ret -= 1;
			borrow = false;
		}

		if (ret < 0)
		{
			ret += 10;
			borrow = true;
		}

		result.push_back(ret + '0');
		i--;
	}

	string retStr;
	auto it = result.rbegin();
	for (; it != result.rend(); ++it){
		if (*it != '0'){
			break;//把0过滤掉 
		}
	}
	for (; it != result.rend(); ++it){
		retStr.push_back(*it);
	}
	//100000
	if (minor){
		retStr.insert(retStr.begin(), '-');
	}

	return retStr;
}

int main(){
	BigInt int4("-354565489454645231");
	BigInt int5("41326354687656452898965765453");
	cout << int4 - int5 << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcoder-9905

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值