大整数的四则运算----减法

题目:输入两个正整数num1,num2。(0<num<10^1000),计算这两个数的差。

在前面的大整数的加法里已经分析过(大整数的四则运算----加法),所以话不多说,直接上重点。还是对应位之间的运算,但是减法不同于加法,加法具有交换律,所以两个数哪个在前哪个在后都无所谓。但减法却不行,所以为了计算,我们首先要知道num1,num2到底哪个大?所以需要一个比较函数,如下。
Code:

int compare(string s1, string s2)  //s1>s2  返回2;   s1<s2  返回1;   s1==s2  返回0;
{
	int len = s1.length() - s2.length();
	if (len > 0)
		return 2;
	else if (len < 0)
		return 1;
	else  //一样长
	{
		for (int i = 0; i < s1.length(); i++)
		{
			if (s1[i] > s2[i])
				return 2;
			else if (s1[i] < s2[i])
				return 1;
			else
				continue;
		}
		return 0;
	}
}

然后开始实现减法运算,第一步,(补齐),不再赘述。第二步,交换,我们要始终让sum1里储存大的那个数,sum2里放小的,这边便于下面的循环遍历。所以根据前面的比较函数,进行可能的交换。如下。
Code:

	int len = num1.length() - num2.length(), flag = compare(num1, num2);
    (flag == 1)      //始终让num1>num2
	{
		string temp = num2;
		num2 = num1;
		num1 = temp;
	}

然后就是最重要的循环遍历实现减法了,在这一步里类比加法,思想相同,但细节不同。加法会产生可能的进位,但是减法可能需要借位。(想必大家都能理解),所以仍然需要定义一个mod,如果需要借位,mod赋值-1,否则是0。如下。
Code:

	int mod = 0;    //借位
	string ans = num1;
	for (int i = num1.length() - 1; i >= 0; i--)  //总是num1-num2
	{
		if ((num1[i] - '0' + mod) >= (num2[i] - '0'))
		{
			ans[i] = ((num1[i] - '0') + mod) - (num2[i] - '0') + '0';
			mod = 0;
		}
		else
		{
			ans[i] = (num1[i] - '0' + mod) + 10 - (num2[i] - '0') + '0';
			mod = -1;
		}
	}

最后一步,细节处理,与加法时相同,需要处理掉前面多余的0。(注意:实现减法前,我们已经手动让sum1>sum2,所以在实行最后一次减法时,一定不会“借位”。)但是正是由于交换,所以最后需要根据flag判断得到的结果是正还是负,如果是负数,需要额外加 ‘-’,如下。
Code:

	char TempAns[1000];
	int k = 0, pos = 0;
	for (int i = 0; i < ans.length(); i++)
	{
		if (ans[i] != '0' || pos==1)
		{
			TempAns[k++] = ans[i];
			pos = 1;
		}
	}	
	TempAns[k] = '\0';
	string FinalAns = TempAns;
	if (flag == 1)
		FinalAns = '-' + FinalAns;

完整(函数)Code:

int compare(string s1, string s2)  //s1>s2  返回2;   s1<s2  返回1;   s1==s2  返回0;
{
	int len = s1.length() - s2.length();
	if (len > 0)
		return 2;
	else if (len < 0)
		return 1;
	else  //一样长
	{
		for (int i = 0; i < s1.length(); i++)
		{
			if (s1[i] > s2[i])
				return 2;
			else if (s1[i] < s2[i])
				return 1;
			else
				continue;
		}
		return 0;
	}
}


string substr(string num1, string num2)
{
	int len = num1.length() - num2.length(), flag = compare(num1, num2);
	if (len > 0)   //补齐
	{
		string ss(len, '0');
		num2 = ss + num2;
	}
	else if(len < 0)
	{
		string ss(-len, '0');
		num1 = ss + num1;
	}
	if (flag == 1)      //始终让num1>num2
	{
		string temp = num2;
		num2 = num1;
		num1 = temp;
	}
	int mod = 0;    //借位
	string ans = num1;
	for (int i = num1.length() - 1; i >= 0; i--)  //总是num1-num2
	{
		if ((num1[i] - '0' + mod) >= (num2[i] - '0'))
		{
			ans[i] = ((num1[i] - '0') + mod) - (num2[i] - '0') + '0';
			mod = 0;
		}
		else
		{
			ans[i] = (num1[i] - '0' + mod) + 10 - (num2[i] - '0') + '0';
			mod = -1;
		}
	}
	char TempAns[1000];
	int k = 0, pos = 0;
	for (int i = 0; i < ans.length(); i++)
	{
		if (ans[i] != '0' || pos==1)
		{
			TempAns[k++] = ans[i];
			pos = 1;
		}
	}	
	TempAns[k] = '\0';
	string FinalAns = TempAns;
	if (flag == 1)
		FinalAns = '-' + FinalAns;
	if (pos)
		return FinalAns;
	else
		return  "0";

}

ps:博主能力有限,如果读者发现什么问题,欢迎私信或评论指出不足。欢迎读者询问问题,乐意尽我所能解答读者的问题。欢迎评论,欢迎交流。谢谢大家!

发布了46 篇原创文章 · 获赞 10 · 访问量 1000

猜你喜欢

转载自blog.csdn.net/lyqptp233/article/details/104766585