大数相乘与大数相加

// BigNumMulti.cpp : 定义控制台应用程序的入口点。
//

//大数相乘

#include<iostream>
#include<string>
using namespace std;

class Solution
{
public:
	string BigNumMulti(string s1, string s2)
	{ 
		//不需判断是否含有正负号,这个可以在输入s1,s2时处理
		if (s1.length() == 0)
			return NULL;
		if (s2.length() == 0)
			return NULL;
		int* result = new int[s1.length() + s2.length()];     //结果最多有s1.length() + s2.length()位
		int len = s1.length() + s2.length();
		memset(result, 0, sizeof(int)*len);
		int res;
		int mul_carry;   //乘法进位
		int add_carry;
		for (int i = s2.length() - 1; i >= 0; i--)  //被乘数
		{
			mul_carry = 0;
			add_carry = 0;
			for (int j = s1.length() - 1; j >= 0; j--)
			{
			    res = (s2[i] - '0')*(s1[j] - '0')+mul_carry;
				mul_carry = (res / 10);  
				res = (res % 10);
				result[i + j + 1] = result[i + j + 1] + res + add_carry;
				add_carry = result[i + j + 1] / 10;
				result[i + j + 1] =( result[i + j + 1] % 10);
			}
			result[i] = result[i] + mul_carry+add_carry;
		}
		string str;
		int index = 0;
		for (; index< len;index++)
			if (result[index] != 0)
				break;
		for (; index < len; index++)
			str.push_back('0' + result[index]);
		return str;
	}
};

int main()
{
	Solution S;
	string s1 = "1232132121111122";
	string s2 = "100";
	string res = S.BigNumMulti(s1, s2);
	cout << res << endl;
}


// BignumAdd.cpp : 定义控制台应用程序的入口点。
//

#include<iostream>
#include<string>
using namespace std;
 
//数字输入的时候带上正负号
bool compare(string s1, string s2)    //比较绝对值大小
{
	if (s1.length() != s2.length())
		return s1.length() > s2.length();
	for (int i = 1; i < s1.length(); i++)
	{
		if (s1[i] <= s2[i])
			return false;
	}
	return true;
}

string BignumAdd(string s1,string s2)
{
	
	int flag = 0;   //结果正负标志,默认为正
	if (s1.length() == 0 || s2.length() == 0)
		return "";
	if (s1.length() < s2.length())    //保证第一个字符串的长度不小于第二个
	{
		string t = s1;
		s1 = s2;
		s2 = t;
	}
	
	int* result = new int[s1.length()]; //多了一个符号位
	memset(result, 0, s1.length()*sizeof(int));
	if (s1[0] == s2[0])   //同号相加
	{
		int add_carry = 0;        //进位
		int j = s2.length() - 1;
		for (int i = s1.length() - 1; i >= 1; i--)
		{
			if (j >= 1)     //最短的序列还没加完
				result[i] = (s1[i] - '0') + (s2[j] - '0') + add_carry;
			else
				result[i] = (s1[i] - '0') + add_carry;
			add_carry = (result[i] / 10);
			result[i] = (result[i] % 10);
			j--;
		}
		result[0] = add_carry;   
		if (s1[0] == '-')
			flag = 1;     //结果为负
	}
	else         //异号相加
	{
		
		//异号相加时,用绝对值大的数减去绝对值小的数
		if (s1[0] == '-')  //第一个为负数
		{
			
			if (!compare(s1, s2))   //abs(s1)<=abs(s2)
			{
				string t = s1;
				s1 = s2;
				s2 = t;     //交换
			}
			else
				flag = 1;    //结果为负
		}
		else     //第二个为负数
		{
			
			if (!compare(s2, s1))   //abs(s2)<=abs(s1)
			{
				flag = 0;
			}
				
			else     //abs(s2)>abs(s1)
			{
				string t = s1;
				s1 = s2;
				s2 = t;     //交换
				flag = 1;        //结果为负
			}
		}
		
		//交换完毕,abs(s1)>=abs(s2)
		//cout << s1 << "," << s2 << endl;
		int j = s2.length() - 1;
		for (int i = s1.length() - 1; i >= 1; i--)
		{
			if (j >= 1)      //较小的序列还未减完
			{
				if (s1[i] < s2[j])   //需要借位
				{
					result[i] = (s1[i] - '0') + 10 - (s2[j]-'0');
					int k = i-1;
					while (s1[k] =='0')     //在s1中依次向左找出第一个不为0的数,进行借位
						k--;
					
					
					s1[k] = s1[k] - 1;       //借位
					for (int p = k + 1; p < i; p++)
					{
						s1[p] = '9';    //更新被借位和借位之间的数
					}
				}
				else  //不需要借位
				{
					result[i] = s1[i] - s2[j];
				}
			}
			else //较小的序列运算完毕
			{
				result[i] =s1[i]-'0';
				
			}
			j--;
		}
		
	}
	string str;
	if (flag)
		str.push_back('-'); //负数
	int index;
	for (int i = 0; i < s1.length(); i++)
	{
		index = i;
		if (result[i] != 0)
			break;
	}
	for (int i = index; i < s1.length(); i++)
		str.push_back(result[i] +'0');
	if (index == s1.length())
		str.push_back('0');          //结果为0
	return str;
}


int main()
{
	string str1 = "-0";
	string str2 = "+1000001";
	string str = BignumAdd(str1, str2);
	cout << str << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值