1. 程式人生 > >【重載運算符+壓位】高精度模板

【重載運算符+壓位】高精度模板

cor font 比較 返回 重載 algorithm == 轉換 一個

昨天做一道DP的題(矩陣取數遊戲),本來是很簡單的,但是要用高精度,又不想用__int128水過去(誰讓NOIP不讓),於是自己打了一個小時,最後掛了。。。

於是本蒟蒻痛定思痛,感覺高精度還是重載運算符好用,就花了幾個小時打了一個高精度模板:

技術分享圖片
/*采用重載運算符,壓4位
支持高精數輸入與輸出、高精加(減)高精、高精乘低(高)精、高精除(模)低精、高精的比較 
註意:暫不支持負數!!!*/
#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
#include
<algorithm> using namespace std; const int N=128,base=1e4;//base是壓4位的基數 struct HP{ private: int a[N],len; inline void clear(HP &x){int &end=x.len;while(!x.a[end]&&end>1) --end;}//清除前導0 public: HP(){ //結構體初始化 memset(a,0,sizeof a);len=0; }
/*以下是高精度的輸入與輸出*/ void init_i(int x) {//用int初始化高精度數 stack<char> st;string s; while(x){ st.push(x%10+0); x/=10; } while(!st.empty()) s+=st.top(),st.pop();//其實就是把int轉換為string再調用init_s() init_s(s); } //註意因為是壓4位的,所以輸入和輸出都要特殊處理
void init_s(string s){//用string初始化高精度數 int l=s.length(); for(int i=0;i<=l;++i){ int j=(l-i+3)/4; a[j]=(a[j]<<1)+(a[j]<<3)+(s[i]^48); } len=(l+3)/4; } void print(){//輸出高精度數 printf("%d",a[len]); for(int i=len-1;i>0;--i) for(int j=base/10;j>0;j/=10) printf("%d",a[i]/j%10); puts(""); } /*以下是重載運算符*/ HP operator +(const HP &x){//高精加高精 HP res;res.len=max(len,x.len);int k=0; for(int i=1;i<=res.len;++i){ res.a[i]=a[i]+x.a[i]+k; k=res.a[i]/base; res.a[i]%=base; } if(k>0) res.a[++res.len]=k; return res; } HP operator -(const HP &x){//高精減高精(註意這裏默認被減數大於減數,否則會出錯) HP res=*this;//相當於用res拷貝被減數 for(int i=1;i<=len;++i){ res.a[i]-=x.a[i]; if(res.a[i]<0) --res.a[i+1],res.a[i]+=base; } clear(res); return res; } HP operator *(const int &x){//高精乘低精 HP res=*this; for(int i=1;i<=len;++i) res.a[i]*=x; for(int i=1;i<=len;++i) res.a[i+1]+=res.a[i]/base,res.a[i]%=base; int &end=res.len; while(res.a[end+1]>0){++end;res.a[end+1]+=res.a[end]/base,res.a[end]%=base;} return res; } HP operator *(const HP &x){//高精乘高精 HP res;res.len=len+x.len; for(int i=1;i<=len;++i) for(int j=1;j<=x.len;++j){ res.a[i+j-1]+=a[i]*x.a[j]; res.a[i+j]+=res.a[i+j-1]/base; res.a[i+j-1]%=base; } clear(res); return res; } HP operator /(const int &x){//高精除低精 HP res;res.len=len; int k=0; for(int i=len;i>0;--i){ k=k*base+a[i]; res.a[i]=k/x; k%=x; } clear(res); return res; } int operator %(const int &x){//高精模低精 int k=0; for(int i=len;i>0;--i){ k=k*base+a[i]; k%=x; } return k;//其實跟高精除低精差不多的,只不過不用存res,返回的是k } bool operator <(const HP &x)const{//重載小於號 (可以仿造重載大於號) if(len==x.len){ int i; for(i=len;a[i]==x.a[i]&&i>1;--i); if(i>=1) return a[i] < x.a[i]; else return false; } else return len < x.len; } }; HP max(HP a,HP b){ if(a<b) return b; return a; } HP min(HP a,HP b){ if(a<b) return a; return b; } HP a,b,ans; string sa,sb; int main() { cin>>sa>>sb; a.init_s(sa);b.init_s(sb); ans=a*b; ans.print(); return 0; }
View Code

註意暫不支持負數,如果發現有bug歡迎指出。

想粘板子就粘吧,打得醜我承認

2018-10-20

【重載運算符+壓位】高精度模板