進來的時候如果沒看見除法,說明我也還不會,會了的話我會補充上去的。如果要看的除法的,得去看别人的了。
目錄
初始化:
加法:
減法:
乘法:
輸出:這個是重點!!!!!!!!!!!
完整代碼:
如果你是從我的“P1601 A+B Problem(高精)”這篇文章來的話,可以看一下壓位計算,更加的快捷友善。
高精度計算就是因為超過了資料表達的類型,從用其他的方式來進行計算。
壓位就是說将一長串的數字分割開來,來單獨進行儲存,進而不會發生超過範圍。
初始化:
可以看到 k 其實就是控制一個int裡面有多少位,你可以自己設定,但如果太大了的話 乘法就有可能越界,如果隻是加減法可以适當的調整大小。
讀入還是得用string類型,沒辦法确實太大了
後面的輸出裡面會說到int類型的一個缺陷。
void Initialization(string str,int num[]){//初始化,用數組的第一位來儲存裡面有幾位
int n=str.length(),k=1,j=1;
for(int i=1;i<=n;i++){
if(k==10000){//表示用的10000進制,也可以自己改進制,但是如果太高的話,乘法和除法不好處理
j++;
k=1;
}
num[j]+=k*(str[n-i]-'0');
k=k*10;
}
num[0]=j;
return;
}
加法:
我是建立了一個數組來存放結果,也可以就利用那兩個數組進行運算,但我懶了(其實是不怎麼會,怕出錯)
關鍵點1:就是在于進位,要記得每次都要判斷是否大于10000,我使用10000進制的,如果你改成了其他的,這個數字跟k相同就行
關鍵點2:就是會多一位出來,我代碼裡面也寫了是關鍵,你得判斷多出來的一位裡面有沒有東西,如果有就得加進去。
void addition(int num1[],int num2[]){//加法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=max(num1[0],num2[0]);
for(int i=1;i<=result[0];i++){
result[i]+=num1[i]+num2[i];
if(result[i]>=10000){//則要進行進位
result[i]-=10000;
result[i+1]++;//往前進位
}
}
//下面是關鍵
if(result[result[0]+1]>0){//類似于9999+1,則會多一位出來,就要判斷是否多了一位。
result[0]++;
}
cout<<result;
}
減法:
同樣是建立的數組。
關鍵點1:跟加法不一樣,你得借位,是以是跟0進行比較,并且記得借了一位,要減去
關鍵點2:這裡判斷有沒有多是用 while 循環,跟加法不一樣,他有可能會一直借位,是以得一直判斷。
void subtraction(int num1[],int num2[]){//減法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=max(num1[0],num2[0]);
for(int i=1;i<=result[0];i++){
result[i]+=num1[i]-num2[i];
if(result[i]<0){//要向前借位
result[i]+=10000;
result[i+1]--;
}
}
//下面也是關鍵
while(result[result[0]]==0&&result[0]>1){//将前面多餘的0删除
result[0]--;
}
cout<<result;
}
乘法:
建立。
這個比加法就要難,相當于是多個加法的疊加,而且每次加的時候不是在同一個位置加,會往前跑一個。
進位就不說了。
result[i+j-1]+=num1[i]*num2[j];//減1是為了從第一位開始
這一行代碼如果不能了解的話,可以去列一下豎式,我相信肯定都會明白的,就是往前移一個相加。總不能不會列豎式吧,這要是不會我也沒辦法了
後面就是判斷前置0的 while 循環了。
void multiplication(int num1[],int num2[]){//乘法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=num1[0]+num2[0]+1;
for(int i=1;i<=num1[0];i++){
for(int j=1;j<=num2[0];j++){//就是豎式算法一樣,一步步來求
result[i+j-1]+=num1[i]*num2[j];//減1是為了從第一位開始
result[i+j]+=result[i+j-1]/10000;//進位
result[i+j-1]%=10000;
}
}
//下面是關鍵
while(result[result[0]]==0&&result[0]>0){//就是把前面多餘的0删除
result[0]--;
}
cout<<result;
}
輸出:
這次可沒有建立了嗷!
這個輸出其實也可以用其他的方式來輸出,但那樣就得自己去看是不是滿4位了。
我先說為什麼要滿4位輸出
因為int類型裡面存放的時候 “0000” 它是看成 “0”來存放的,比如 10000 放在 int 裡面就會變成
int[1]=0,int[2]=1;這樣輸出的話就會變成10。
是以如果不用流輸出的話,就得自己判斷 int 裡面有幾位,然後要補幾個0,但是用流輸出的話,就可以直接用函數。就很友善,不用自己寫,這還不爽?如果不會流的話,可以去學一下,很快的。
還有就是運算符的重載,學一下也很快的。都是模闆,套一下就好!
ostream&operator<<(ostream &o,int result[]){
o<<result[result[0]];
for(int i=result[0]-1;i>0;i--){
o.width(4);//每次都要輸出4位
o.fill('0');//如果不夠4位則要補齊,因為int類型裡面的0000會被當作0
o<<result[i];
}
return o;
}
完整代碼:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<vector>
using namespace std;
const int Maxn=10000;
ostream&operator<<(ostream &o,int result[]){
o<<result[result[0]];
for(int i=result[0]-1;i>0;i--){
o.width(4);//每次都要輸出4位
o.fill('0');//如果不夠4位則要補齊,因為int類型裡面的0000會被當作0
o<<result[i];
}
return o;
}
void Initialization(string str,int num[]){//初始化,用數組的第一位來儲存裡面有幾位
int n=str.length(),k=1,j=1;
for(int i=1;i<=n;i++){
if(k==10000){//表示用的10000進制,也可以自己改進制,但是如果太高的話,乘法和除法不好處理
j++;
k=1;
}
num[j]+=k*(str[n-i]-'0');
k=k*10;
}
num[0]=j;
return;
}
void addition(int num1[],int num2[]){//加法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=max(num1[0],num2[0]);
for(int i=1;i<=result[0];i++){
result[i]+=num1[i]+num2[i];
if(result[i]>=10000){//則要進行進位
result[i]-=10000;
result[i+1]++;//往前進位
}
}
//下面是關鍵
if(result[result[0]+1]>0){//類似于9999+1,則會多一位出來,就要判斷是否多了一位。
result[0]++;
}
cout<<result;
}
void subtraction(int num1[],int num2[]){//減法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=max(num1[0],num2[0]);
for(int i=1;i<=result[0];i++){
result[i]+=num1[i]-num2[i];
if(result[i]<0){//要向前借位
result[i]+=10000;
result[i+1]--;
}
}
//下面也是關鍵
while(result[result[0]]==0&&result[0]>1){//将前面多餘的0删除
result[0]--;
}
cout<<result;
}
void multiplication(int num1[],int num2[]){//乘法
int result[Maxn];
memset(result,0,sizeof(result));
result[0]=num1[0]+num2[0]+1;
for(int i=1;i<=num1[0];i++){
for(int j=1;j<=num2[0];j++){//就是豎式算法一樣,一步步來求
result[i+j-1]+=num1[i]*num2[j];//減1是為了從第一位開始
result[i+j]+=result[i+j-1]/10000;//進位
result[i+j-1]%=10000;
}
}
//下面是關鍵
while(result[result[0]]==0&&result[0]>0){//就是把前面多餘的0删除
result[0]--;
}
cout<<result;
}
int main(){
string str1,str2;
cin>>str1>>str2;
int num1[Maxn];
int num2[Maxn];
memset(num1,0,sizeof(num1));//将數組裡面的全部值變成0
memset(num1,0,sizeof(num1));//将數組裡面的全部值變成0
Initialization(str1,num1);
Initialization(str2,num2);
multiplication(num1,num2);
system("pause");
return 0;
}