【问题描述】
编写程序实现两个超长正整数(每个最长80位数字)的减法运算。
【输入形式】
从键盘读入两个整数,要考虑输入高位可能为0的情况(如00083)。
1. 第一行是超长正整数A;
2. 第二行是超长正整数B;
【输出形式】
输出只有一行,是长整数A减去长整数B的运算结果,从高到低依次输出各位数字。要求:若结果为0,则只输出一个0;否则输出的结果的最高位不能为0,并且各位数字紧密输出。
【输入样例】
234098
134098703578230056
【输出样例】
-134098703577995958
【样例说明】
进行两个正整数减法运算, 234098 -134098703578230056 = -134098703577995958。
解题思路:这个整数过长,明显超出int的范围,因此采用处理字符串的方法进行处理,将这个数字用字符的形式读入之后再转换为整数的形式,然后采用我们所学得列竖式计算的方法对其进行处理。需要注意的是,题目中给出输入的整数最高位可能为0,我们要将最高位的0给去除。
参考代码:
#include <stdio.h>
#include <string.h>
char shuzi1[100],shuzi2[100];//用于使用字符串的形式读入两个数
int num1[100],num2[100];//用于储存将字符串形式转换为整数
int mark,flag1,flag2,l1,l2;//mark用于判断第一个数和第二个数谁大,flag1和flag2表示输入的数的第一个不为零的数的位置,l1代表第一个数字的位数,l2同理
int cunfang(int len1,int len2)
{
int i;
for(i=0;i<len1;i++)
num1[i]=shuzi1[l1-i-1]-'0';//将第一个数字中的有效数字存入num1中
for(i=0;i<len2;i++)
num2[i]=shuzi2[l2-i-1]-'0';//将第二个数字中的有效数字存入num2中
}
int xiangjian(int len)
{
int i;
if(mark==1)//说明第一个数字大
{
for(i=0;i<len;i++)
{
if(num1[i]<num2[i])
{
num1[i]=num1[i]+10;
num1[i+1]=num1[i+1]-1;
}//如果较小就借一位数字
num1[i]=num1[i]-num2[i];
}
for(i=len-1;i>=0,len>0;i--)
{
if(num1[i]==0)
len--;
else
break;
}//将数字中的无效的0去掉
for(i=len-1;i>=0;i--)
printf("%d",num1[i]);//输出结果
}
else//说明第二个数字大(要用第二个数字减去第一个数字然后加上负号)
{
for(i=0;i<len;i++)
{
if(num2[i]<num1[i])
{
num2[i]=num2[i]+10;
num2[i+1]=num2[i+1]-1;
}//如果较小就借一位数字
num2[i]=num2[i]-num1[i];
}
for(i=len-1;i>=0,len>0;i--)
{
if(num2[i]==0)
len--;
else
break;
}//将无效的0去掉
if(len==0)
printf("0");
else
{
printf("-");
for(i=len-1;i>=0;i--)
printf("%d",num2[i]);
}
}
}
int main()
{
int len1,len2,i=0;
scanf("%s%s",shuzi1,shuzi2);//读取数字
len1=strlen(shuzi1);
l1=len1;
len2=strlen(shuzi2);
l2=len2;//判断数字的长度
for(i=0;i<len1;i++)
{
if(shuzi1[i]!='0')
{
flag1=i;
break;
}
}//判断数字头有多少个无效的0
for(i=0;i<len2;i++)
{
if(shuzi2[i]!='0')
{
flag2=i;
break;
}
}//判断数字头有多少个无效的0
len1=len1-flag1;
len2=len2-flag2;//得到有效的长度
if(len1>len2||strcmp(shuzi1,shuzi2)>0&&len1==len2)//第一个数大于第二个数
{
mark=1;
cunfang(len1,len2);
xiangjian(len1);
}
else//第一个数小于等于第二个数
{
mark=2;
cunfang(len1,len2);
xiangjian(len2);
}
}