高精度算法整合【数组实现】【通用模板】

一、你需要知道

1、高精度数无法被int或者long long类型直接保存,需要用字符数组或者string类来保存。

2、字符串保存的高精度数,下标【0】存放着高精度数的最高位,下标【字符串长度-1】存放着高精度数的个位。

3、为了方便计算,符合人类正常的计算思维,需要将高精度数进行倒置,倒置后用int数组保存高进度数,此时下标【0】存放个位,下标【长度-1】存放最高位

4、为了本套模版的通用性,将模拟加、减、乘、除的过程单独分离出来处理,模拟完成后再去进行进位或者借位操作(对比代码理解)

5、计算完成后必须删除前导零,例如000180,应该输出180。

二、高精度算法

高精度加法步骤:

1. 从个位数开始,逐位相加,保留进位;

2. 如果有进位,继续向高位相加,直到所有位数相加完毕。

#include<bits/stdc++.h>
using namespace std;
const int N=205;
string s1,s2;
int a[N],b[N],c[N];
int main()
{
	cin>>s1>>s2;
	//倒置
	int l1=s1.size(),l2=s2.size(),l3=max(l1,l2)+1;
	for(int i=0;i<l1;i++) a[l1-1-i]=s1[i]-'0';
	for(int i=0;i<l2;i++) b[l2-1-i]=s2[i]-'0';
	//模拟加法
	for(int i=0;i<l3;i++)
		c[i]=a[i]+b[i];
	//处理进位、留个位
	for(int i=0;i<l3;i++)
	{
		c[i+1]+=c[i]/10;
		c[i]%=10;
	} 
	//删去前导零 
	while(c[l3-1]==0 && l3>1) l3--;
	for(int i=l3-1;i>=0;i--) cout<<c[i]; 
	return 0;
}

高精度减法步骤:

1. 从个位数开始,逐位相减,借位不够时向更高位借位;

2. 如果需要借位,继续向更高位相减,直到所有位数相减完毕。

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
const int N=205;
int a[N],b[N],c[N];
int main()
{
	cin>>s1>>s2;
	int l1=s1.size(),l2=s2.size(),l3=max(l1,l2);
	//倒置 
	for(int i=0;i<l1;i++)	a[l1-1-i]=s1[i]-'0'; 
	for(int i=0;i<l2;i++)   b[l2-1-i]=s2[i]-'0';
	//模拟减法 
	for(int i=0;i<l3;i++)
		c[i]=a[i]-b[i];
	//处理借位
	for(int i=0;i<l3;i++)
	{
		if(c[i]<0){
			c[i+1]--;
			c[i]+=10;
		}
	 } 
	//删除前导零 
	while(c[l3-1]==0&&l3>1) l3--;
	for(int i=l3-1;i>=0;i--) cout<<c[i]; 
	return 0;
 }

高精度乘法步骤:

1. 逐位相乘,保留进位;

2. 将每一位的乘积相加,得到最终结果。

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[105],b[105],c[205]={0}; 
int main()
{
	cin>>s1>>s2;
	//提前倒置两个大数 
	int l1=s1.size(),l2=s2.size(),l3=l1+l2;
	//i是字符串原本的下标、j是字符串倒置后的下标 
	for(int i=0,j=l1-1;i<l1;i++,j--) a[j]=s1[i]-'0';
	//公式实现: 将下标i--->下标 l2-i-1 
	for(int i=0;i<l2;i++) b[l2-i-1]=s2[i]-'0';
	//开始模拟乘法 
	//乘法公式 c[i+j]+=a[i]*b[j] 
	for(int i=0;i<l1;i++)
		for(int j=0;j<l2;j++)
			c[i+j]+=a[i]*b[j];
	//进位、留个位 
	for(int i=0;i<l3;i++)
	{
		c[i+1]+=c[i]/10;//第i位进位到i+1位
		c[i]%=10; //个位的留到第i位 
	}
	//删去前导0  
	while(c[l3-1]==0 && l3>1)	l3--; 
	//输出 
	for(int i=l3-1;i>=0;i--)  cout<<c[i];
	return 0;
 }

高精度除以低精度步骤:

1. 从被除数的最高位开始,逐位与除数相除,得到商和余数;

2. 将余数乘以10,再与下一位进行除法运算,直到所有位数都计算完毕。

#include<bits/stdc++.h>
using namespace std;
string s1;
int a[110],c[110],b; 
int main()
{
	//低精度除数为13
	b=13; 
	cin>>s1;
	int l1=s1.size();
	//倒置 
	for(int i=0;i<l1;i++) a[l1-1-i]=s1[i]-'0';
	// 模拟除法竖式
	int l3=l1-1;//商的长度,可以优化成l1-l2+1  
	int r=0;//余数初始化为0 
	for(int i=l1-1;i>=0;i--){
		c[i]=(r*10+a[i])/b;
		r=(r*10+a[i])%b;
	}
	//删除前导零
	while(c[l3-1]==0&&l3>1) l3--;
	//逆序输出
	for(int i=l3-1;i>=0;i--)
		cout<<c[i]; 
	cout<<endl<<r;
	return 0;
}

高精度除以高精度步骤:

1. 将被除数和除数都倒置,从被除数的最高位开始逐步进行除法运算。

2. 比较被除数(一部分)和除数的大小,如果被除数比较大,则减去一次除数,商对应位+1

3. 如果被除数小,再与被除数的下一位结合后,重复第2步,直至所有位数都计算完毕。

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
const int N=305;
int a[N],b[N],c[N],l1,l2,l3; 

bool cmp(int i)被除数a从最高位到第i位,是否大于等于除数b(从最高位到第0位)
{
	//比b最高位还要高位的位置上有数字 
	if(a[i+l2]>0) return true;
	
	for(int j=l2-1;j>=0;j--)//从高位到低位比较 
	{
		if(a[i+j]>b[j]) return true;
		else if(a[i+j]<b[j]) return false; 
	}
	//相等 
	return true;
}

int main()
{
	cin>>s1>>s2;
    //倒置
	l1=s1.size(),l2=s2.size(),l3=l1-l2+1;
	for(int i=0;i<l1;i++) a[l1-1-i]=s1[i]-'0';
	for(int i=0;i<l2;i++) b[l2-1-i]=s2[i]-'0';
    //模拟除法
	for(int i=l3-1;i>=0;i--){//从高位开始 
		while(cmp(i)){//够减 ,做一次减法 
			c[i]++;//对应位的商加一 
			//模拟减法 
			for(int j=0;j<l2;j++){//从低位开始 
				if(a[i+j]>=b[j]) a[i+j]-=b[j];//减得下 
				else{//减不下 
					a[i+j]=a[i+j]+10-b[j];
					a[i+j+1]--;//向高位借位 
				}
			} 
		}
	}
	
	//商、余数前导零 
	while(c[l3-1]==0&&l3>1) l3--;
	while(a[l2-1]==0&&l2>1) l2--;
	for(int i=l3-1;i>=0;i--) cout<<c[i];
	cout<<endl;
	for(int i=l2-1;i>=0;i--) cout<<a[i]; 
 	return 0;
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值