關於大整數乘法和加法的一些整理
阿新 • • 發佈:2018-11-08
例如,有兩個大整數,a和b,其中a、b位數都是大於10的。我們知道,在做OJ的題時,碰到大整數的乘法,不能直接用a*b得到結果,那樣是不對的,所以需要用陣列來儲存。
首先,很簡單,定義兩個陣列(足夠長),s1和s2,分別用來儲存大整數a和b,因為我們需要用來相乘,而乘法是從最後一位開始乘法的,所以我們需要將a和b用陣列的形式倒序儲存。
int s1[100] = {0};
int s2[100] = {0};
int a, b;
cin >> a, b;
int i = 1;
while (a)
{
s1[i++] = a % 10;
a /= a;
}
int lena = i -1;
i = 1;
while (b)
{
s2[i++] = b % 10;
b /= b;
}
int lenb = i-1;
這樣,陣列s1和s2就分別倒序儲存了大整數a和b。
此時,我們需要對陣列s1和s2進行相乘,並將結果保留下來。我們知道,按照我們自然的乘法,是將大數放在上面,小數放在下面來進行相乘運算。現在,陣列s1和s2分別儲存了整數a和整數b,並且是倒序的方式。這樣,s1的第一位就是數a的個位數,s2的第一位就是b的個位數,依次儲存。此時,我們需要將長度比較長的放在外層迴圈,作為乘法的主體,較短的那個放在內層迴圈,就和我們平常做乘法一樣,依次用下面的變數去乘上面的每一位。
for (i=1; i<=lena; i++)
{
for (j=1; j<=lenb; j++)
{
res[i+j-1] += a[i] * b[j];
if (res[i+j-1]>9)
{
res[i+j] += res[i+j-1] / 10;
res[i+j-1] %= 10;
}
}
}
if (res[lena+lenb-1]>9)
{
res[lena+lenb] += res[lena+lenb-1] / 10;
res[lena+lenb-1] %= 10;
lena = lena + lenb ;
}
else lena = lena + lenb -1;
初始化陣列res為0即可。
計算完成後,陣列res儲存的就是s1*s2的結果,並且其長度為lena;
此時res儲存的結果也是按照倒序排列的,所以如果要輸出a*b的結果,需要倒序輸出。
有了前面的大整數的乘法,加法其實更簡單,同樣將大整數放入兩個陣列中,倒序放置,
int s1[100] = {0};
int s2[100] = {0};
int a, b;
cin >> a, b;
int i = 1;
while (a)
{
s1[i++] = a % 10;
a /= a;
}
int lena = i-1;
i = 1;
while (b)
{
s2[i++] = b % 10;
b /= b;
}
int lenb = i-1;
然後,對s1和s2進行相加,和乘法不同的是,我們將長度較小的那個放在外層迴圈:
if (lena < lenb)
{
int cmp = 0;
for (int i=1; i<=lena; ++i)
{
s2[i] += s1[i] + cmp;
if (s2[i] >= 10)
{
cmp = s2[i] / 10;
s2[i] %= 10;
}
}
for (int i=lena+1; i<=lenb; ++i)
{
s2[i] += cmp;
if (s2[i] >= 10)
{
cmp = s2[i] / 10;
s2[i] %= 10;
if (i == lenb)
{
s2[i+1] += cmp;
lenb = lenb + 1;
break;
}
}
}
}
這是假設s1的長度比s2小,同理,當s2比s1小時,方法一樣,最後結果存入較長的那個陣列中。此時,結果陣列儲存值的順序也是倒序的。