有一段時間沒和大家更新算法,今天來和大家研究一下,簡單高精度加法。
首先,例:求A+B的值。
這個應該很簡單::
cin>>a;
cin>>b;
cout<<a+b
對於類型範圍內的都可以用。但如果a和b都是5000位以內或者更高的呢,這個樸素求法,就gg了。
由於待處理的數據超過了任何一種數據類型所能容納的範圍,因此必須採用數串形式傳輸入,並將其轉化爲整形數組,其轉化方式是該數字字符減去
“0”或者48即可該數組的每一個元素對應一位十進制數,由其下標順序指明位序號。例如計算1234567890+987654321的值。
初始化如圖所示。
對整型數組a[]和b[]按算術運算規則進行運算之前,需要用變量記錄兩組整數數組的最大元素個數,即最大位數,這是因爲由於高精度運算的結果
可能使得數據長度發生增減(最高位進位)。
運算過程如圖所示。
不知道大家看到這有沒有點頭緒,不妨動手寫寫看。
給點提示:
寫一個初始化整型數組函數;
int add( )
{
}
再寫一個字符串轉爲整型數組函數:void init( )
{
}
最後寫一個輸出到相加的結果函數:void output( )
{
}
最後貼上源代碼:
#include<iostream>
#include<fstream>
#define MAXN 5001
using namespace std;
int add(int x[],int y[],int z[],int len)
{
int i,j,r;
for(j=0;j<len;++j) //從下標0開始逐位相加到len-1
{
z[j] += x[j]+ y[j]; //相加結果存到z[]
for(i=j;i<len;++i)
{
if(z[i]>=10) //如果當前位數的值超過了10,則要進位處理
{
z[i+1] += z[i]/10; //此處如改爲++z{i+1],效率更高
z[i] -= 10; //或者是z[i]%=10,但速度稍慢
if(z[len] > 0)
len++;
if(z[i+1] < 10) //小優化
break;
}
}
}
return len; //返回位數
}
void init(int x[],string str,int len) //字符串轉爲整型數組
{
for(int i=0;i<len;i++)
x[len-i-1] = str[i]-'0'; //倒序轉換
}
void output(int z[],int len) //輸出到相加的結果
{
for(int i=len-1;i>=0;i--)
cout<<z[i];
cout<<"\n";
}
int main()
{
string str1,str2;
int a[MAXN]={0},b[MAXN]={0},z[MAXN]={0}; //初始化爲0
int la,lb,len;
cin>>str1;
cin>>str2;
la = str1.size();
lb = str2.size();
init(a,str1,la); //初始化整型數組
init(b,str2,lb);
if(la >= lb) //確定a和b的最大位數
len = add(a,b,z,la); //取最長位la
else
len = add(b,a,z,lb); //取最長位lb
output(z,len);
return 0;
}
測試數據:1234567890+123456789
結果:
測試數據:123456789123456789123456789123456789123456789+987654321987654321987654321987654321
結果:
希望大家能夠舉一反三,減法,乘法,除法也都能寫出來!
下次爲大家帶來揹包問題的算法講解。