第二课-高精度

其中高精度的题目不乏就是大数的加减乘除;

说明:其实大部分的处理上,加法用的程度稍微更多一点。减法虽然也用,但是在边界处理,其实就是实现函数上弯弯绕更多了一些

加法(应该是最简单的):过多的说明我就不再去进行补充了,真的是最基本的了。
其实最重要的vector我们实现的加法函数。
一定要注意函数的定义,我就写错了很多次。实在没注意

#include <iostream>
#include <vector>
const int N=1e6+10;
using namespace std;
vector<int> add(vector<int>& A,vector<int>& B){
	vector<int> C;
    int carry=0;
    for(int i=0;i<A.size()||i<B.size();i++){
        if(i<A.size()) carry+=A[i];
        if(i<B.size()) carry+=B[i];
        C.push_back(carry%10);
        carry/=10;
    }
    if(carry) C.push_back(1);
    return C;
}
int main(){
    string a,b;//123456
    vector<int> A,B;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');//6,5,4,3,2,1
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
    auto C=add(A,B);
    for(int i=C.size()-1;i>=0;i--){
        cout<<C[i];
    }
    return 0;
}

高精度减法:

#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector<int> A,vector<int> B){
	if(A.size()!=B.size()) return A.size()>B.size();
	else{
		for(int i=A.size()-1;i>=0;i--){
			if(A[i]!=B[i]){
				return A[i]>B[i];
			}
		}	
	}
	return true;
}
//一定要搞清楚sub函数的关系 
vector<int> sub(vector<int> &A,vector<int> &B){
	vector<int> C;
	int carry=0;
	for(int i=0;i<A.size();i++){
		carry=A[i]-carry;
		if(i<B.size()) carry-=B[i];
		C.push_back((carry+10)%10);//这个其实就是综合两种情况
		if(carry<0){//这个表示单独的某一个数位相减小于0
		//123-55 ---->显然在各位上3-5肯定是小于0的 
			carry=1; 
		} 
		else carry=0;
	}
	//但是此时C的位数是大位数,也就是位数=max(A,B)的位数
	//比如125-123 ,vectorC的结果是2 0 0 (注意这里的顺序)
	//back()函数处理的数字的末尾。 
	while(C.size()>1&&C.back()==0) C.pop_back(); 
	return C;
}
int main(){
	string a,b;
    cin>>a>>b;
    vector<int> 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');
    //auto C=cmp(A,B)?sub(A,B):(-sub(B,A)); 千万注意不能这么写,第二章情况处理不了
	//我第一次图旁边就是这么写得,但是这样就导致了符号重载。 
	if(cmp(A,B)) {
		auto C=sub(A,B);
		for(int i=C.size()-1;i>=0;i--) cout<<C[i];
	}
	else {
		auto C=sub(B,A);
		cout<<"-";
    	for(int i=C.size()-1;i>=0;i--) cout<<C[i];
	}
	return 0;
} 

高精度的相关题目 Acwing,pat
高精度加法 Acwing-791. 高精度加法
高精度减法 Acwing-792. 高精度减法
高精度加法+字符串模拟 pat-1023 Have Fun with Numbers (20分)

关于pat的那一题的高精度我要去进行说明:long long类型表示的数字范围是10的19次方,显然还是不满足的。而且题目仅仅是对本数字去进行翻倍。与上面的我给的两个模版相比,真的是简单了不少。
题解如下:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm> 
using namespace std;
int main(){
	string num;
	cin>>num;
	vector<int> a;
	
	for(int i=num.size()-1;i>=0;i--) a.push_back(num[i]-'0');//减去一个偏移量,从字符转换一个整数 
	//怎么翻倍;注意翻倍之后可能位数会相加 
	vector<int> b;
	int t=0;//设置一个进位 
	for(int i=0;i<a.size();i++){
		int sum=a[i]+a[i]+t;
		//把当前的位进入进来,而且判断是否大于10(取模就解决了)
		b.push_back(sum%10);
		t=sum/10; 
	} 
	//检查最高位是否还产生了进位, 
	if(t) b.push_back(t);
	
	//如果判断两个数组中,包含的数是一样的?
	vector<int> c=b;
	sort(a.begin(),a.end());
	sort(c.begin(),c.end());
	if(a==c) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	
	for(int i=b.size()-1;i>=0;i--){
		cout<<b[i];
	} 
	return 0;
} 

高精度乘法:

题目列举 leetcode,acwing
大整数乘法 43. 字符串相乘
大整数乘法 Acwing-793. 高精度乘法

列出我所写出的方法吧。有别于大雪菜的写法。他的写法是一个是大整数,另外一个是稍微小一点的整数。但是我的写法一定是包含他的写法的。

#include <iostream> 
using namespace std;
#include <vector> 
//分析过程如下 
//223 
//  9 
//-------
//个位:结果的个位:3*9%10=2   进位:carry =3*9/10=2 
//十位:结果的十位:(2*9+2)%10=0  进位:carry =(2*9+2)/10=2 
//百位:结果的百位:(2*9+2)%10=0  进位:carry =(2*9+2)/10=2 
//千位:结果的千位:
//用循环判断 
//if(carry) C.push_back(carry)
vector<int> mul(vector<int>& num1,vector<int>& num2){
	//大概的长度,默认为若干个0 
	//使用列表初始化 
	vector<int> C(num1.size()+num2.size(),0);
	for(int i=0;i<num1.size();i++){
		for(int j=0;j<num2.size();j++){
			int sum=C[i+j]+num1[i]*num2[j];
			C[i+j]=sum%10;
			C[i+j+1]+=sum/10;//进位 	
		}
	} 
	//取出前导0 
	while(C.size()>1&&C.back()==0) C.pop_back(); 
	return C;
}
int main(){
	string a,b;
	cin>>a>>b;
	vector<int> 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');
	auto c=mul(A,B);
	for(int i=c.size()-1;i>=0;i--){
		cout<<c[i];
	}
	return 0;
}

大整数除法:

猜你喜欢

转载自blog.csdn.net/weixin_44110100/article/details/106959006