高精度算法

本篇文章是依据哔哩哔哩上up主麦克老师讲算法的视频做的笔记,该视频简单易懂,十分推荐,推荐看视频。

【高精度算法全套(加,减,乘,除,全网最详细)】 https://www.bilibili.com/video/BV1LA411v7mt/?share_source=copy_web&vd_source=5ebb8be0e4868c8d7bbd5edd0ee2e04d


int类型的取值范围10^9,long long类型为10^18,当要取得的数据大于这个范围就需要使用高精度了。

高精度加法

问题描述:求A加B

   a4 a3 a2 a1

+ b4 b3 b2 b1

--------------------

c5 c4 c3 c2 c1

算法核心

c[i]+=a[i]+b[i];

c[i+1]=c[i]/10;

c[i]=c[i]%10;

 例题为洛谷P1601 A+B Problem(高精)

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式        

分两行输入。a,b<=10^500。

输出格式

输出只有一行,代表 a+b 的值。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int c[505];
int main()
{
	size_t asbut=0, bsbut=0;
	string a, b;
	cin >> a >> b;
	//反转输入内容方便后期计算
	reverse(a.begin(), a.end());
	reverse(b.begin(), b.end());

	asbut = a.size(), bsbut = b.size();
	int i;
	for (i = 0; i < max(asbut, bsbut); i++)
	{
		if (i > min(asbut, bsbut)-1) {				//当相加的数位数不一样时,需要对长的那位单独做,因为用的是string,不单独做的话,会访问错误
			if (a.size() == min(asbut, bsbut)) {
				c[i] += b[i]-'0';
				c[i + 1] = c[i] / 10;
				c[i] = c[i] % 10;
			}
			if (b.size() == min(asbut, bsbut)) {
				c[i] += a[i] - '0';
				c[i + 1] = c[i] / 10;
				c[i] = c[i] % 10;
			}
		}
		else {									//如果相加的两位数都是用int数组保存好的话,就不需要上面判断位数不相等的部分了
		c[i] += (a[i] - '0') + (b[i] - '0');
		c[i+1] = c[i] / 10;
		c[i] = c[i] % 10;
		}
	}
	if (c[i] ==0 ) {
		i--;
	}
	for (int j = i; j >=0; j--) {
		cout << c[j];
	}
	

	return 0;
}

感觉还是全部用数组做方便了


高精度减法

问题描述:求A-B

   a4 a3 a2 a1

- b4 b3 b2 b1

--------------------

c5 c4 c3 c2 c1

算法核心:

如果a<b,则需要交换a和b;

如果a[i]<b[i],需要高位借1当10用

if(a[i]<b[i]){

        a[i+1]--;

        a[i]+=10;

}

c[i]=a[i]-b[i];

例题为洛谷题目p2142高精度减法

题目描述

高精度减法。

输入格式

两个整数 a,b(第二个可能比第一个大)。

输出格式

结果(是负数要输出负号)。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int a[11000],b[11000],c[11000];
int main()
{
	int flag = 0;
	string s1, s2;
	cin >> s1 >> s2;
	size_t la, lb, lc;
	//判断s1和s2的长度,s1小于s2的话就互相交换
	if (s1.size() < s2.size()) {
		flag = 1;
		swap(s1, s2);
	}
	//当s1和s2一样长是,就比较对应位置字符的字典大小,s1小于s2的话,互相交换
	if (s1.size() == s2.size()) {
	if (lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end())){
		flag = 1;
		swap(s1, s2);
	}
	}
	//将字符串的长度装起来,注意la,lb,lc的型别
	la = s1.size();
	lb = s2.size();
	lc = max(la, lb);
	//将字符串对应的字符,转换成整型保存起来,方便后面进行计算
	for (int i = 0; i < la; i++) {
		a[la - i] = s1[i] - '0';
	}
	for (int i = 0; i < lb; i++) {
		b[lb - i] = s2[i] - '0';
	}
	//进行减法计算
	for (int i = 1; i <= lc;i++) {
		if (a[i] < b[i]) {
			a[i + 1]--;
			a[i] += 10;
		}
		c[i] = a[i] - b[i];
	}
	//去掉前置0
	while (c[lc] == 0 && lc > 1) {
		lc--;
	}
	//判断是否进行了交换,进行了的话,则输出-
	if (flag == 1) {
		cout << '-';
	}
	for (int i = lc; i > 0; i--) {
		cout << c[i];
	}
	cout << endl;
	return 0;
}

高精度乘法

问题描述A*B:

   a4 a3 a2 a1

*             b2 b1

--------------------

c5 c4 c3 c2 c1

核心算法:

a[i]*b[i]=c[i+j-1];

考虑进位

c[i+j-1]+=a[i]*b[j];

c[i+j]+=c[i+j-1]/10;

c[i+j-1]%=10;

 例题为p1303 A*B problem

题目描述

给出两个非负整数,求它们的乘积。

输入格式

输入共两行,每行一个非负整数。

输出格式

输出一个非负整数表示乘积。

#include<iostream>
#include<string>
using namespace std;
int a[10000], b[10000],c[10000];
int main(){
	string s1, s2;
	cin >> s1 >> s2;
	size_t la, lb, lc;
	la = s1.size(), lb = s2.size();
	//将类型转换成int进行保存,方便计算
	for (int i = 1; i <= la; i++) {
		a[i] = s1[la - i]-'0';
	}
	for (int i = 1; i <= lb; i++) {
		b[i] = s2[lb - i]-'0';
	}
	//进行乘法计算了
	lc = la + lb;
	for (int i = 1; i <= la; i++) {
		for (int j = 1; j <= lb; j++) {
			c[i + j - 1] += a[i] * b[j];
			c[i + j] += c[i + j - 1] / 10;
			c[i + j - 1] %= 10;
		}
	}
	//去前置0
	while (c[lc] == 0 && lc > 1)lc--;
	//打印 
	for (int i = lc; i > 0; i--) {
		cout << c[i];
	}
	cout << endl;

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值