《编程思维与实践》1064.A-B(Big Integer)
题目
思路
两个大整数做减法有可能出现结果为负的情况,因此结构体BIGINT需要补充符号位sign,
因为减法是个位对齐进行操作,为了方便起见,本题还是采用逆序(个位开始)存储.
注意到本题的两个整数均非负,所以不需要考虑转化为加法的情况(减负数等价于加正数).
A-B有以下几种情况:
1.A位数比B大,直接从个位开始减即可,不足注意借位;
2.A位数比B小,结果的符号位变为-1,转化为B-A;
3.A位数与B位数相同,此时需要比对A和B的大小,应该从最高位开始比:
如果从最高位开始A有一位大于B,那么就能保证A>B;
如果从最高位开始A有一位小于B,那么就能保证A<B;
如果该位A等于B,则比较下一位.
之后进行类似1和2的操作即可.
注意的点:
做完减法后记得去除前置0(保留最后一个).
代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 500
typedef struct{int cnt,v[N],sign;}BIGINT;
BIGINT sub(BIGINT S, BIGINT T,int sign); //两个大整数相减 subtraction
int main()
{
char s1[501],s2[501];
while(scanf("%s",s1)!=EOF&&scanf("%s",s2)!=EOF)
{
BIGINT A={strlen(s1),{0}},B={strlen(s2),{0}};
for(int i=0;i<strlen(s1);i++)
{
A.v[A.cnt-1-i]=s1[i]-'0';
}
for(int i=0;i<strlen(s2);i++)
{
B.v[B.cnt-1-i]=s2[i]-'0';
}
BIGINT ans=sub(A,B,1);
if(ans.sign==-1)
{
printf("-");
}
for(int i=ans.cnt-1;i>=0;i--)
{
printf("%d",ans.v[i]);
}
printf("\n");
}
return 0;
}
BIGINT sub(BIGINT S, BIGINT T,int sign) //两个大整数相减 两个大整数均非负
{
if(S.cnt<T.cnt)
{
return sub(T,S,-1);
}
else if(S.cnt==T.cnt&&sign!=-1)
{
for(int i=T.cnt-1;i>=0;i--) //注意是从最高位开始比
{
if(T.v[i]<S.v[i])
{
break;
}
else if(T.v[i]>S.v[i])
{
return sub(T,S,-1);
}
}
}
BIGINT R={S.cnt,{0},sign};
int flag=0; //借位
for(int i=0;i<R.cnt;i++)
{
if(S.v[i]-flag-T.v[i]>=0)
{
R.v[i]=S.v[i]-T.v[i]-flag;
flag=0;
}
else
{
R.v[i]=S.v[i]-T.v[i]-flag+10;
flag=1;
}
}
for(int i=R.cnt-1;i>=1&&R.v[i]==0;i--)
{
R.cnt--;
}
return R;
}