注:昨天的高减重载小于运算符写错了,应该是倒序从高位到低位 ——2019.4.20
bool operator <(const num &p,const num &q){//比较大小
if(p.a[0]<q.a[0]) return true;
if(p.a[0]>q.a[0]) return false;
for(int i=p.a[0];i>=1;--i){//倒序
if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
}
return false;
}
高精度加法
/***************************************
User:Mandy.H.Y
Language:c++
Problem:luogu1601 A+B Problem(压位)
Algorhithm:High Precision Addition
****************************************/
#include<bits/stdc++.h>
using namespace std;
const int power=4; //压位压四位
const int base=1e4;
const int maxn=505;
struct num{
int a[maxn];
num(){memset(a,0,sizeof(a));}
int &operator [](int x){return a[x];}//重载中括号
num(char *s){
memset(a,0,sizeof(a));
int len=strlen(s);
a[0]=(len+power-1)/power;//计算位数
for(int i=0,t=0,w=0;i<len;++i,w*=10){
if(i%power==0) {w=1,++t;}//最好写成这种形式
a[t]+=(s[i]-'0')*w;
}
}
void print(){
printf("%d",a[a[0]]);
for(int i=a[0]-1;i>0;--i) printf("%04d",a[i]);//printf("%0*d",power,a[i]);
}
}ans,p,q;
num operator +(num &p,num &q){//重载了中括号所以不用const
int cur=0,len=max(p[0],q[0]);
for(int i=1;i<=len;++i){
cur+=i<=p[0]?p[i]:0;
cur+=i<=q[0]?q[i]:0;
p[i]=cur%base;cur/=base;
}
if(cur) p[++len]=cur;
p[0]=len;//注意更新长度
return p;
}
char p1[maxn],q1[maxn];
int lenp,lenq;
int main(){
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
reverse(p1,p1+lenp);reverse(q1,q1+lenq);
p=num(p1);q=num(q1);
ans=p+q;
ans.print();
return 0;
}
高精度减法
/**************************************
User:Mandy.H.Y
Language:c++
Pronblem:luogu2142 A-B Problem
Algorhithm:High Precision Subtraction
**************************************/
#include<bits/stdc++.h>
using namespace std;
const int power=4;
const int base=1e4;
const int maxn=1e4+5;
struct num{
int a[maxn];
num(){memset(a,0,sizeof(a));}
num(char *s,int len){
memset(a,0,sizeof(a));
a[0]=(len+power-1)/power;
for(int t=0,w=1,i=len-1;i>=0;w=(w<<1)+(w<<3),--i){//倒序省去reverse
if((len-1-i)%power==0){++t,w=1;}
a[t]+=(s[i]^48)*w;
}
}
void print(){
printf("%d",a[a[0]]);
for(int i=a[0]-1;i>0;--i) printf("%0*d",power,a[i]);
}
}p,q,ans;
bool operator <(const num &p,const num &q){//比较大小
if(p.a[0]<q.a[0]) return true;
if(p.a[0]>q.a[0]) return false;
for(int i=p.a[0];i>=1;--i){//倒序
if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
}
return false;
}
num operator -(num &p,num &q){
int len=max(p.a[0],q.a[0]);
for(int i=1;i<=len;++i){
p.a[i]-=i<=q.a[0]?q.a[i]:0;
if(p.a[i]<0) p.a[i]+=base,p.a[i+1]-=1;//借位
}
while(p.a[0]>1&&p.a[p.a[0]]==0) --p.a[0];
return p;
}
char p1[maxn],q1[maxn];
int lenp,lenq;
int main(){
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp),q=num(q1,lenq);
if(q<p) ans=p-q;
else putchar('-'),ans=q-p;
ans.print();
return 0;
}
高精度乘法
/*********************************************
User:Mandy.H.Y
Language:c++
Problem:luogu 1303 A*B Problem
Algorithm: High Precision Multiplication
**********************************************/
#include<bits/stdc++.h>
using namespace std;
const int power=4;
const int base=1e4;
const int maxn=2e3+5;
struct num{
int a[maxn<<1];
num(){memset(a,0,sizeof(a));}
num(char *s,int len){
memset(a,0,sizeof(a));
a[0]=(len+power-1)/power;
for(int t=0,w=1,i=len-1;i>=0;w=(w<<1)+(w<<3),--i){
if((len-1-i)%power==0) w=1,++t;
a[t]+=(s[i]^48)*w;//注意+=
}
}
void print(){
printf("%d",a[a[0]]);
for(int i=a[0]-1;i>0;--i) printf("%0*d",power,a[i]);
}
}ans,p,q;
char p1[maxn],q1[maxn];
int lenp,lenq;
num operator *(const num &p,const num &q){
num b;
for(int i=1;i<=p.a[0];++i){
int cur=0;
for(int j=1;j<=q.a[0];++j)
cur+=b.a[i+j-1]+p.a[i]*q.a[j],b.a[i+j-1]=cur%base,cur/=base;
//cur+=b.a[i+j-1]+p.a[i]*q.a[j]累加 b.a[i+j-1]
b.a[i+q.a[0]]=cur;
}
b.a[0]=q.a[0]+p.a[0];//得到大致位数
while(b.a[0]>1&&b.a[b.a[0]]==0) --b.a[0];//除去前导0
return b;
}
int main(){
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp);q=num(q1,lenq);
ans=p*q;
ans.print();
return 0;
}
整合
/**************************
User:Mandy.H.Y
Language:c++
Problem:
Algorithm: High Precision
***************************/
#include<bits/stdc++.h>
using namespace std;
const int power=4;
const int base=1e4;
const int maxn=2e3+5;
struct num{
int a[maxn<<1];
num(){memset(a,0,sizeof(a));}
int &operator [](int x){return a[x];}//重载中括号
num(char *s,int len){
memset(a,0,sizeof(a));
a[0]=(len+power-1)/power;
for(int t=0,w=1,i=len-1;i>=0;w=(w<<1)+(w<<3),--i){
if((len-1-i)%power==0) w=1,++t;
a[t]+=(s[i]^48)*w;//注意+=
}
}
void add(int k) { if (k || a[0]) a[ ++a[0] ] = k; } //在末尾添加一个数,除法的时候要用到
void re() { reverse(a+1, a+a[0]+1); }
void print(){
printf("%d",a[a[0]]);
for(int i=a[0]-1;i>0;--i) printf("%0*d",power,a[i]);
}
}ans,p,q;
char p1[maxn],q1[maxn];
int lenp,lenq;
num operator +(num &p,num &q){//重载了中括号所以不用const
int cur=0,len=max(p[0],q[0]);
for(int i=1;i<=len;++i){
cur+=i<=p[0]?p[i]:0;
cur+=i<=q[0]?q[i]:0;
p[i]=cur%base;cur/=base;
}
if(cur) p[++len]=cur;
p[0]=len;//注意更新长度
return p;
}
bool operator <(const num &p,const num &q){//比较大小
if(p.a[0]<q.a[0]) return true;
if(p.a[0]>q.a[0]) return false;
for(int i=p.a[0];i>=1;--i){//倒序
if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
}
return false;
}
num operator -(num &p,num &q){
int len=max(p.a[0],q.a[0]);
for(int i=1;i<=len;++i){
p.a[i]-=i<=q.a[0]?q.a[i]:0;
if(p.a[i]<0) p.a[i]+=base,p.a[i+1]-=1;//借位
}
while(p.a[0]>1&&p.a[p.a[0]]==0) --p.a[0];
return p;
}
num operator / (num &p,num &q) //注意const不要冲突
{
num x, y;
for (int i = p.a[0];i >= 1;--i) //从最高位开始取数
{
y.add(p.a[i]); //把数添到末尾(最低位),这时候是高位在前,低位在后
y.re(); //把数反过来,变为统一的存储方式:低位在前,高位在后
while ( !(y < q) ) //大于等于除数的时候,如果小于的话,其实答案上的该位就是初始的“0”
y = y - q, ++x.a[i]; //看能减几个除数,减几次,答案上该位就加几次。
y.re(); //将数反过来,为下一次添数做准备
}
x.a[0] = p.a[0];
while (x.a[0] > 0 && !x.a[x.a[0]]) --x.a[0];
return x;
}
num operator *(const num &p,const num &q){
num b;
for(int i=1;i<=p.a[0];++i){
int cur=0;
for(int j=1;j<=q.a[0];++j)
cur+=b.a[i+j-1]+p.a[i]*q.a[j],b.a[i+j-1]=cur%base,cur/=base;
b.a[i+q.a[0]]=cur;
}
b.a[0]=q.a[0]+p.a[0];//得到大致位数
while(b.a[0]>1&&b.a[b.a[0]]==0) --b.a[0];//除去前导0
return b;
}
int main(){
/*
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp);q=num(q1,lenq);
ans=p*q;
ans.print();
return 0;
*/
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp);q=num(q1,lenq);
ans=p+q;
ans.print();
return 0;
/*
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp),q=num(q1,lenq);
if(q<p) ans=p-q;
else putchar('-'),ans=q-p;
ans.print();
return 0;
*/
}
练习
luogu1255
/************************
User:Mandy.H.Y
Language:c++
Problem:luogu 1255 Staircase
Algorithm:High Precision Addition
************************/
#include<bits/stdc++.h>
using namespace std;
const int power=4;
const int base=1e4;
const int maxn=5005;
struct num{
int a[maxn];
num(){memset(a,0,sizeof(a));}
int &operator [](int x){return a[x];}
void print(){
printf("%d",a[a[0]]);
for(int i=a[0]-1;i>0;--i) printf("%04d",a[i]);
}
}ans[5];
int n;
num operator +(num &p,num &q){
int cur=0,len=max(p[0],q[0]);
for(int i=1;i<=len;++i){
cur+=i<=p[0]?p[i]:0;
cur+=i<=q[0]?q[i]:0;
p[i]=cur%base,cur/=base;
}
p[0]=len;//注意继承长度
if(cur) p[++p[0]]=cur;
return p;
}
int main(){
scanf("%d",&n);
if(n==1) {puts("1");return 0;}
if(n==2) {puts("2");return 0;}
ans[1].a[0]=1,ans[2].a[0]=1;ans[1].a[1]=1,ans[2].a[1]=2;
for(int i=3;i<=n;++i){
ans[i%3]=ans[(i+1)%3]+ans[(i+2)%3];
}
ans[n%3].print();
return 0;
}
luogu1604
/***************************
User:Mandy.H.Y
Language:c++
Problem:luogu1604 Planet
Algorithm:High Precision
***************************/
#include<bits/stdc++.h>
using namespace std;
const int power=1;
const int maxn=2e4+5;
int n,base;
struct num{
int a[maxn];
num(){memset(a,0,sizeof(a));}
int &operator [](int x){return a[x];}
num(char *s,int len){
a[0]=len;
for(int i=len-1;i>=0;--i){
if(isdigit(s[i])) a[len-i]=s[i]^48;
else a[len-i]=s[i]-'A'+10;
}
}
void print(){
for(int i=a[0];i>0;--i){
if(a[i]<10) printf("%d",a[i]);
else printf("%c",a[i]-10+'A');
}
}
}p,q,ans;
char p1[maxn],q1[maxn];
int lenp,lenq;
num operator +(num &p,num &q){
int cur=0,len=max(p[0],q[0]);
for(int i=1;i<=len;++i){
cur+=i<=p[0]?p[i]:0;
cur+=i<=q[0]?q[i]:0;
p[i]=cur%base,cur/=base;
}
if(cur) p[++len]=cur;
p[0]=len;
return p;
}
int main(){
scanf("%d",&base);
scanf("%s%s",p1,q1);
lenp=strlen(p1);lenq=strlen(q1);
p=num(p1,lenp);q=num(q1,lenq);
ans=p+q;
ans.print();
return 0;
}
部分引自:https://www.cnblogs.com/hnqw1214/p/6351321.html