高精度篇————
乘除法
咳咳,最近一直在研究該怎麼講接下來的高精度
先說另一件事
家長的一位朋友說,高精度加法可以改進
如果在化字符爲數字時把加法做了
可以省三個10000的一維數組
因此我把改進後的代碼也奉上
#include <iostream> #include <math.h> using namespace std; string add(string s1,string s2) { string ans=""; bool f=false; int i,l=max(s1.size(),s2.size()); while(s1.size()<l) s1='0'+s1; while(s2.size()<l) s2='0'+s2; for(i=l-1;i>=0;i--) { int x1,x2,xs; x1=int(s1[i]-'0'); x2=int(s2[i]-'0'); xs=x1+x2; if(f) xs++; f=false; if(xs>9) f=true; xs%=10; ans=char(xs+'0')+ans; } if(f) ans='1'+ans; return ans; } int main() { string v1,v2; cin>>v1>>v2; cout<<add(v1,v2)<<endl; return 0; }
也請大家多多給我糾錯以及評論
我會努力改進的
當然,剛纔說了那麼多,都是爲了引出今天的主題
剛纔的方法看似省去了空間,但在乘法上可就不行嘍~
目錄
1.乘法思想
2.乘法實現
3.插曲(一會你就知道了)
4.除法思想
5.除法實現
1.乘法思想
和加減法一樣,用數組存起來,再做運算
但是注意,這裏要用1個雙重循環
因爲拿一位去乘字符串,不僅耗時間,也耗空間
因此我們採用一位一位單個去乘
這時,雙重循環就能體現出它的作用了
因爲在做乘法時,十位及以上要空格
比如1234,做第二個123時會空一個格
這時就可以用雙重循環實現
2.乘法實現
實在不方便打字,具體看註釋吧
#include<iostream> #include<cmath> using namespace std; string mul(string s1,string s2) { int i,j,a[10005]={0},b[10005]={0},s[10005]={0},w=0,l1=s1.size(),l2=s2.size(),l=max(l1,l2);//定義 string ans=""; for(i=0;i<l1;i++) a[l1-i-1]=int(s1[i]-'0');//存數組,看過加減法的都明白 for(i=0;i<l2;i++) b[l2-i-1]=int(s2[i]-'0'); for(i=0;i<l1;i++)//開始雙重循環做乘法 for(j=0;j<l2;j++)//第i位可以看成10的i-1次方,存數組前挪了一位,因此根據冪的加法就是s[i+j] s[i+j]+=a[i]*b[j]; for(i=0;i<2*l;i++)//和加法一樣,整理 { s[i+1]+=s[i]/10; s[i]%=10; if(s[i]!=0) w=i; } for(i=0;i<=w;i++) ans=char(s[i]+'0')+ans;//返回爲字符串 return ans; } int main() { string v1,v2; cin>>v1>>v2; cout<<mul(v1,v2)<<endl; return 0; }
其實大體上和加法差不多,但是要理解其中的方法
3.插曲
這就要牽扯到開頭講的方法
你要是用正在乘的時候整理
你會發現——
痛不欲生!
因爲這種方法只能算一次,而乘法涉及多位數
因此不可以省空間
那麼,除法可不可以呢?
我的回答很肯定:不行!
4.除法思想
首先,除法與前三個算法都不一樣
比如光看豎式
就會發現除法是個異類
因此,不能使用正常的算法
那麼引入一種新的思想
來分析一下除法的思想:
一是上面的豎式
二是_中有幾個_
第一肯定可以,但是很難模擬
於是用第二種方法實現
5.除法實現
詳細看註釋
#include<iostream> #include<cmath> using namespace std; bool str_Judge_size(string s1,string s2)//判斷s1和s2的大小 { if(s1.size()>s2.size()||(s1.size()==s2.size()&&s1>=s2)) return true;//如果s1位數大 return false;//或兩數位數相同且s1大返回正,否則返回負 } string sub(string s1,string s2)//高精度減法就不用再說了吧^_^ { int i,a[10005]={0},b[10005]={0},s[10005]={0},l1=s1.size(),l2=s2.size(),l=max(l1,l2),w=0; string ans=""; for(i=0;i<l1;i++) a[l1-i-1]=int(s1[i]-'0'); for(i=0;i<l2;i++) b[l2-i-1]=int(s2[i]-'0'); for(i=0;i<l;i++) s[i]=a[i]-b[i]; for(i=0;i<=l;i++) { if(s[i]<0) { s[i+1]--; s[i]+=10; } if(s[i]!=0) w=i; } for(i=0;i<=w;i++) ans=char(s[i]+'0')+ans; return ans; } string div(string s1,string s2)//做除法的兩個高精度數 { int s[10005]={0};//s是最終的商,每一個s表示一位數 int l1=s1.size(),l2=s2.size();//兩個字符串的長度 int w=0;//表示商的最高位 string ans="",v1=s1,v2;//v1和v2做差 while(str_Judge_size(v1,s2))//當商s2比v1大時,即還能減 { int x=0;//減數擴的倍數 v2=s2; while(str_Judge_size(v1,v2+"0"))//還可以擴倍 { v2+='0';//相減的數如果能再大一位,就*10,即在字符串末尾添加‘0 ’ x++;//位數++ } v1=sub(v1,v2);//二數相減 s[x]++;//s位++ if(x>w) w=x;//如果位數大於x,x替換成w } for(int i=0;i<=w;i++) ans=char(s[i]+'0')+ans;//把結果轉換回string返回 return ans; } int main() { string v1,v2;//高精度兩數 cin>>v1>>v2;//輸入 cout<<div(v1,v2)<<endl;//輸出 return 0; }
感謝大家的支持,下期再見