高精度减法(A-B problem)

/*--- A-B problem 高精度 ---*/
#include<bits/stdc++.h>
using namespace std;
int max(int a,int b)
{
	return a>=b?a:b;
}
int main(void)
{
	char s[101000],p[101000];	//输入的字符串 
	int lena,lenb;			//表示字符串的长度  
	int a[101000],b[101000];	//转化成的数 
	int sub[101000];		//每一位的差 
	int cnt;			//用来检测最后一位不是0的首位  
	int tot=-1;		//两个数位数相同时,检测第一个相减不为0的位置 
	
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(sub,0,sizeof(sub));
	
	cin>>s>>p;
	lena=strlen(s);
	lenb=strlen(p);
	
	for(int i=0;i<=lena-1;i++){ a[lena-1-i]=s[i]-'0'; }
	for(int i=0;i<=lenb-1;i++){ b[lenb-1-i]=p[i]-'0'; }
	
	if(lena>lenb)
	{
		for(int i=0;i<=max(lena,lenb)-1;i++)
		{
			sub[i]=a[i]-b[i];
		}
		for(int i=0;i<=max(lena,lenb)-1;i++)
		{
			while(sub[i]<0)
			{
				sub[i]=sub[i]+10;
				sub[i+1]--;
			}
		}
		for(int i=max(lena,lenb)-1;i>=0;i--)
		{
			if(sub[i]!=0){ cnt=i; break; } 
		}
		for(int i=cnt;i>=0;i--)
		cout<<sub[i];
	}
	else if(lena<lenb)
	{
		for(int i=0;i<=max(lena,lenb)-1;i++)
		{
			sub[i]=b[i]-a[i];
		}
		for(int i=0;i<=max(lena,lenb)-1;i++)
		{
			while(sub[i]<0)
			{
				sub[i]=sub[i]+10;
				sub[i+1]--;
			}
		}
		for(int i=max(lena,lenb)-1;i>=0;i--)
		{
			if(sub[i]!=0){ cnt=i; break; } 
		}
		cout<<'-';
		for(int i=cnt;i>=0;i--)
		cout<<sub[i];
	}
	else
	{
		int k=lena;
		for(int i=0;i<=k-1;i++)
		{
			sub[i]=a[i]-b[i];
		}
		for(int i=k-1;i>=0;i--)
		{
			if(sub[i]!=0) tot=i;
		}
		if(tot=-1)
		{
			cout<<0;
		}
		else if(sub[tot]>0) 
		{
			for(int i=0;i<=tot;i++)
			{
				while(sub[i]<0)
				{
					sub[i]=sub[i]+10;
					sub[i+1]--;
				}
			}
			for(int i=tot;i>=0;i--)
			cout<<sub[i];
		}
		else
		{
			for(int i=0;i<=k-1;i++)
			{
				sub[i]=b[i]-a[i];
			}
			for(int i=0;i<=tot;i++)
			{
				while(sub[i]<0)
				{
					sub[i]=sub[i]+10;
					sub[i+1]--;
				}
			}
			cout<<"-";
			for(int i=tot;i>=0;i--)
			cout<<sub[i];
		}			
	}
	return 0;
}

上面的代码是自己写的

/*====Corycle====*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+5;
int read(){
	int s=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=s*10+c-'0';c=getchar();}
	return s*f;
}
char s[N],t[N];
int a[N],b[N],flag;
bool Check(int a[],int b[]){//a<b?
	if(a[0]!=b[0])return a[0]<b[0];
	for(int i=a[0];i>=1;i--){
		if(a[i]!=b[i])return a[i]<b[i];
	}
	return false;
}
int main(){
//	freopen("_.in","r",stdin);
//	freopen("_.out","w",stdout);
	scanf("%s%s",s+1,t+1);
	a[0]=strlen(s+1);b[0]=strlen(t+1);
	for(int i=1;i<=a[0];i++)a[i]=s[a[0]-i+1]-'0';
	for(int i=1;i<=b[0];i++)b[i]=t[b[0]-i+1]-'0';
	if(Check(a,b)){flag=1;swap(a,b);}
	for(int i=b[0];i>=1;i--)a[i]-=b[i];
	for(int i=1;i<=a[0];i++){
		if(a[i]<0){a[i]+=10;a[i+1]--;}
	}
	while(a[0]>=1&&a[a[0]]==0)a[0]--;
	if(flag)printf("-");
	if(!a[0])puts("0");
	else for(int i=a[0];i>=1;i--)printf("%d",a[i]);
	return 0;
}

上面的代码是HJQ大佬写的。代码的简洁度明显简单了很多。

高精度减法与高精度加法并没有实质上的区别,依然是按照列竖式的方式进行模拟即可。要注意的是可能为负数,所以要进行讨论(这里我是直接写的if进行讨论,这样会导致代码的重复性很高,代码冗长,HJQ大佬使用了一个函数来判断,代码简洁度简单了许多)。

注意的东西同样是倒序输入处理再倒序输出,相比于加法而言注意要排除掉前面的0,例如12345-12344=00001,要把前面的0都排除掉,实现方法也很容易,一个while循环就能解决。

posted @ 2022-10-15 00:38  血赤叶红  阅读(222)  评论(0)    收藏  举报