這道題目把我難住了,用普通的算法通不過。查了資料才知道,這道題目屬於大數相乘的問題。
思路和大整數的加法類似,利用乘法的原理解題,用整數數組來解決大數的存儲問題。(因爲用整型類型來存儲大數會發生溢出。)
所謂的乘法原理:是指兩個數相乘,其結果等於一個數與另一個數的每一位上的數字相乘後所得到的數字之和。跟我們筆算兩個數的乘法是一樣的。
例如:125*12 = 5*12+20*12+100*12=1500
網上有很多這道題目的代碼,但都是低位存儲個位的數(也就是說,數組的存儲結果跟實際得到的數字順序上是恰恰相反的,如a[0]存儲的是個位的數。),理解起來很費勁。我終於找到了一個按正常順序存儲的。代碼如下,有詳細的註釋:
#include<iostream>
#include<cstdio>
#include<memory.h>
#define MAX 10000
#define BASE 10000 //這裏寫10,100,1000,10000,1000000都可以,只是要注意輸出格式
int h[MAX];
int main()
{
int i,j,k,carry;
int n;
while(scanf("%d", &n)!=EOF)
{
memset(h,0,MAX*sizeof(int)); //賦值,每一個都置爲0
for(i=1,h[MAX-1]=1; i<=n; ++i) //從i=1一直到i=n,將數組的最後一位置爲1
for(k=MAX-1,carry=0; k>=0; --k) //從最後一位開始相乘,依次向前與每一位相乘,乘積保存在carry中
{
carry+=i*h[k];
h[k]=carry%BASE;
carry/=BASE;
}
for(j=0;j<MAX && h[j]==0; ++j) //從0位開始搜索,找到不爲0的第一個數
;
printf("%d", h[j++]); //輸出第一個不爲0的位,第一位可能不足四位,就地輸出!
for( ;j<MAX; ++j)
printf("%04d", h[j]); //處在中間的值也可能沒有四位,這時候要注意了,往左邊加0,湊足四位,不然答案會出錯!
printf("\n");
}
return 0;
}
根據上面的原理,我寫了一個大數(用數組存儲)與數(用int存儲)的函數:
void Multiply(int bigNum[], int bigLen, int smallNum)
{
/**
**說明:bigNum應該足夠長,個位數存儲在最後一位,高位沒有的置爲0
*/
int i,j,carry=0;
for(i=bigLen-1;i>=0;--i)
{
carry+=smallNum*bigNum[i];
bigNum[i]=carry%10;
carry=carry/10;
}
}
上面函數中,用的是十進制,便於輸出。
完整的例子如下:
#include<iostream>
#include<cstdio>
#include<memory.h>
void Multiply(int bigNum[], int bigLen, int smallNum)
{
/**
**說明:bigNum應該足夠長,個位數存儲在最後一位,高位沒有的置爲0
*/
int i,j,carry=0;
for(i=bigLen-1;i>=0;--i)
{
carry+=smallNum*bigNum[i];
bigNum[i]=carry%10;
carry=carry/10;
}
}
int main()
{
int i;
int a[10]={0,0,0,0,0,0,2,3,4,5};
int b=34;
Multiply(a,10,b);
for(i=0;i<10 && a[i]==0; ++i)
;
for(;i<10;i++)
printf("%d", a[i]);
return 0;
}