题目:输入两个正整数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:博主能力有限,如果读者发现什么问题,欢迎私信或评论指出不足。欢迎读者询问问题,乐意尽我所能解答读者的问题。欢迎评论,欢迎交流。谢谢大家!