02 高精度算法笔记(只有模板,暂未刷题版)

1 序言(some废话&鸡汤)

高精度通常在面试很少会考到,笔试会涉及,但自己想加强自己的逻辑能力,因此看了高精度的加减,乘除就劝退.

鸡汤:学代码,一定不能止步于算法思路,要落实到代码实现上。

2 理论部分

既然目的是训练逻辑能力,普通的加减有哪些步骤?每一步如何用计算机语言去实现呢?至于高精度就再考虑个范围问题即可。
在这里插入图片描述
落实细节
1.A+B 高精度

  • 大整数怎么存?
    int 肯定不行。存储的方式是用数组来存储,且采用倒序存储。可借鉴大端小端法(这里借用某位博主的图方便理解)
    在这里插入图片描述
    因为高精度位数很多,因此输入时以字符串形式输入,再用数组的形式存储即可。
  • 如何加呢?
    我们计算加法的时候,采取对齐方式,逐个进位。
    进位的时候,需保留个位,用取模运算%。
  1. A-B
  • 减法逻辑
    A-B-t(t是借位)一般情况:
    1.>=0够减,直接算A-B-t.
    2.<0 不够减,需借位,A-B+10-t.
  • t借位逻辑
    1.t>=0 => t
    2. t<0 => t+10
  • 高精度减法模板仅适用A>=B,当且仅当A<B时 => -(B-A).

3 代码模板

  • 高精度加法模板
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;
//C=A+B
vector<int> add(vector<int>& A, vector<int>& B) {
	vector<int> C;
	int t = 0; //进位 
	for (int i = 0; i < A.size() || i < B.size(); i++) {
		if (i < A.size()) t += A[i];
		if (i < B.size()) t += B[i];
		C.push_back(t % 10);
		t /= 10;
	}
	if (t) C.push_back(1);
	return C;
}
int main() {
	string a, b;
	vector<int> A, B;  //vector是c++的一种容器,可以随时调整数组长度 动态数组 
	cin >> a >> b; //a='12345'
	for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // 因为是字符串,要变成数字整型,后面得-‘0’.
	for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
	vector<int> C = add(A, B);
// auto指编译器自动推断什么类型 这里等价于vector<int> 
	for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
	return 0;
}
  • 高精度减法模板
    t=1 表示借位, t=0表示无借位
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;
//判断是否A>=B 
//按照字典序比较
bool cmp(vector<int>& A, vector<int>& B) {
	/*
	1.先判断位数是否相等
		1.1 相等判断高位谁大,直到找到不同的数结束
		1.2 高位在最后一位数
	2.不相等,直接输出A>=B
	*/
	if (A.size() != B.size())  return A.size() > B.size();
	for (int i = A.size()-1; i >=0; i--) {
		if (A[i] != B[i]) return A[i] > B[i];
	}
	return true; //相等结果为0
}
//C=A-B
vector<int> sub(vector<int>& A, vector<int>& B) {
	vector<int> C;
	for (int i = 0,t=0; i < A.size(); i++) {
		t = A[i] - t;
		if (i < B.size()) t -= B[i];
		C.push_back((t + 10) % 10); //
		if (t < 0) t = 1;
		else t = 0;
	}
	//去掉前导0
	while (C.size() > 1 && C.back() == 0) {
		C.pop_back();
	}
	return C;
}
int main(){
	string a, b;
	vector<int> A, B;
	cin >> a >> b;
	for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
	if (cmp(A, B)) {
		vector<int> C = sub(A, B);
		for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
	}
	else {
		vector<int> C = sub(B, A);
		printf("-");
		for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值