1. 程式人生 > 其它 >大數(模板)

大數(模板)

參考:

(48條訊息) 大數(加、減、乘、除、低精度*大數)模板詳解(C++)_氵青-風的部落格-CSDN部落格_c++ 大數

模板:

  1 //大數加,減,乘,除,階乘(低精度*大數)
  2 //大數
  3 #include<bits/stdc++.h>
  4 #include<cstring>
  5 using namespace std;
  6 //初始化,補全位數 
  7 void inital(string &a,string &b)
  8 {
  9     while(a.size()<b.size()) a='0'+a;
 10     while
(b.size()<a.size()) b='0'+b; 11 } 12 //找最大值,使a>b 13 void findmax(string &a,string &b) 14 { 15 string cmp; 16 if(a<b) 17 { 18 cmp=a; 19 a=b; 20 b=cmp; 21 } 22 } 23 //刪除第一個'0' 24 bool del(string &a) 25 { 26 if(a[0]=='0') 27 {
28 a.erase(0,1); 29 return true; 30 } 31 else 32 return false; 33 } 34 //刪除全部的'0',基於del 35 void delall(string &a) 36 { 37 while(del(a)) 38 { 39 del(a); 40 } 41 } 42 //大數加法 43 string bigadd(string a,string b) 44 { 45 inital(a,b);//初始化,先補位,使a,b對齊
46 //a,b前都加一個'0'方便進位(例如三位數加三位數最多為四位數) 47 a='0'+a; 48 b='0'+b; 49 //從後往前,按位加 50 for(int i=a.size()-1;i>=0;i--) 51 { 52 //減'0'的ASCII碼,得到準確資料 53 int num1=a[i]-'0'; 54 int num2=b[i]-'0'; 55 //如果相加大於10,進位 56 if(num1+num2>9) 57 { 58 a[i-1]=a[i-1]-'0'+1+'0'; 59 a[i]=num1+num2-10+'0'; 60 } 61 else 62 { 63 a[i]=num1+num2+'0'; 64 } 65 } 66 //刪除最前面的'0' 67 del(a); 68 //cout<<a<<endl; 69 return a; 70 } 71 //大數減法,基本與大數加法相同 72 string bigsub(string a,string b) 73 { 74 inital(a,b); 75 //找到a,b中的最大值,來分別充當減數與被減數 76 findmax(a,b); 77 for(int i=a.size()-1;i>=0;i--) 78 { 79 int num1=a[i]-'0'; 80 int num2=b[i]-'0'; 81 //被減數小於減少,進行借位 82 if(num1<num2) 83 { 84 a[i-1]=a[i-1]-'0'-1+'0'; 85 a[i]=(num1+10-num2)+'0'; 86 } 87 else 88 { 89 a[i]=num1-num2+'0'; 90 } 91 } 92 //刪除a前面全部的'0' 93 delall(a); 94 cout<<a<<endl; 95 return a; 96 } 97 //大數乘法,基於大數加法 98 void bigmul(string a,string b) 99 { 100 //先考慮特殊情況 101 //刪除a,b前面所有的零,若其中一個為空,表示其中一個乘數為0,那麼a*b=0 102 delall(a); 103 delall(b); 104 if(a==""||b=="") 105 { 106 cout<<"0"<<endl; 107 return; 108 } 109 //考慮完特殊情況後初始化a,b 110 inital(a,b); 111 //找到a,b中的最大值,把問題轉化為大數加分 112 findmax(a,b); 113 string res="0";//儲存答案 114 delall(b);//刪除b前所有的'0',把b拆分充當小數 115 for(int i=b.size()-1;i>=0;i--) 116 { 117 int num1=b[i]-'0'; 118 //例如:10*5555=1*55550 119 if(i!=b.size()-1) 120 { 121 a=a+'0'; 122 } 123 //例如5*10轉化為:5個10相加 124 for(int j=1;j<=num1;j++) 125 { 126 res=bigadd(res,a); 127 } 128 } 129 //刪除res前所有的'0' 130 delall(res); 131 cout<<res<<endl; 132 } 133 //大數除法,注意每次判斷前都要補全 134 //相當於求:被除數是除數的幾倍 135 void bigdiv(string a,string b) 136 { 137 inital(a,b);//將要判斷a與b的大小關係,需補全 138 //特殊情況 139 if(a<b) 140 { 141 cout<<"0"<<endl; 142 return; 143 } 144 delall(b); 145 string res="0";//儲存答案 146 string tmp=b;//儲存每次的除數=b*restmp 147 string restmp="1";//倍數 148 for(int i=1;i<=(a.size()-b.size());i++) 149 { 150 //計算a與b相差的位數,即為相差的倍數 151 tmp+='0'; 152 restmp+='0'; 153 } 154 inital(a,b);//將要進行判斷a,b的大小關係,需補全 155 while(a>=b) 156 { 157 inital(a,tmp);//將要判斷a,tmp的大小關係,需補全 158 //將除法轉化為減法 159 if(a>=tmp) 160 { 161 a=bigsub(a,tmp);//a=a-tmp 162 res=bigadd(res,restmp);//答案加上此時的倍數 163 } 164 else 165 { 166 //a<tmp則/10 167 tmp.erase(tmp.size()-1); 168 restmp.erase(restmp.size()-1); 169 inital(a,tmp);//將要判斷a,tmp的大小關係,需補全 170 //將除法轉化為減法,同上 171 if(a>=tmp) 172 { 173 a=bigsub(a,tmp); 174 res=bigadd(res,restmp); 175 } 176 } 177 inital(a,b);//將要判斷下一輪的a,b大小關係,需補全 178 } 179 cout<<res<<endl; 180 } 181 void fac(int n) 182 { 183 int num[10000]; 184 memset(num,0,sizeof(num)); 185 num[0]=1;//儲存位數 186 num[1]=1;//首位初值為1 187 for(int i=1;i<=n;i++) 188 { 189 int len=num[0]; 190 //每一位都乘i 191 for(int j=1;j<=len;j++) 192 { 193 num[j]*=i; 194 } 195 for(int k=1;k<=num[0];k++) 196 { 197 //進位更新num[k]和num[k+1] 198 if(num[k]>9) 199 { 200 num[k+1]+=num[k]/10; 201 num[k]=num[k]%10; 202 } 203 //進位後num[0]++ 204 if(num[num[0]+1]!=0) 205 { 206 num[0]++; 207 } 208 } 209 } 210 //遍歷 211 for(int i=num[0];i>=1;i--) 212 { 213 cout<<num[i]; 214 } 215 cout<<endl; 216 } 217 int main() 218 { 219 string a,b; 220 cin>>a>>b; 221 //bigadd(a,b); 222 //bigsub(a,b); 223 bigmul(a,b); 224 //bigdiv(a,b); 225 //int n; 226 //cin>>n; 227 //fac(n); 228 }