C語言大數乘法---以藍橋杯試題(基礎練習 階乘計算)爲例

大數乘法有很多種的算法,今天我是模擬豎式乘法用於解決大數乘法。

以下便是大數乘法的代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAX 1000

using namespace std;

char beMultiplier[MAX]; //被乘數 
char multiplier[MAX];  //乘數 
int result[MAX];

int getCount(char a[]){
	int count = 0;
	for(int i=0;;i++)
		if(a[i]=='X') break;
		else count++;
	return count-1;
}

char  multiplication(char bemu[],char mu[]){
	int bCount = getCount(bemu);
	int mCount = getCount(mu);
	
	for(int i=mCount-1;i>=0;i--){ //從乘數最後一位開始乘 
		int nowx = mu[i]-'0';
		int spos = mCount - i - 1;
		int c = 0; //進位 
		int bpos = 0;
		for(int j=bCount-1;j>=0;j--){
			int nowy = bemu[j]-'0';
			int m = nowx*nowy; //乘積 
			int r = m%10; //餘數
			result[bpos+spos] += r;
			c = m/10; 
			result[bpos+spos+1] += c;
			if(result[bpos+spos]>=10){
				result[bpos+spos+1] += result[bpos+spos]/10;
				result[bpos+spos] = result[bpos+spos]%10;
			}
			bpos++;
		} 
	}
	int flag = 0;
	for(int i=MAX;i>=0;i--){
		if(result[i]!=0) flag=1;
		if(flag) cout<<result[i];
	}
}

int main()
{
	memset(result,0,sizeof(result));
	memset(beMultiplier,'X',sizeof(beMultiplier));
	memset(multiplier,'X',sizeof(multiplier));
	cin>>beMultiplier>>multiplier;
	multiplication(beMultiplier,multiplier);
	return 0;
}

接下來,在這個程序的基礎上,我們來解決藍橋杯的試題(基礎練習 階乘計算

原題題意:

試題 基礎練習 階乘計算

資源限制
時間限制:1.0s 內存限制:512.0MB
問題描述
  輸入一個正整數n,輸出n!的值。
  其中n!=123*…*n。
算法描述
  n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位,依次類推。
  將a乘以一個整數k變爲將數組A的每一個元素都乘以k,請注意處理相應的進位。
  首先將a設爲1,然後乘2,乘3,當乘到n時,即得到了n!的值。
輸入格式
  輸入包含一個正整數n,n<=1000。
輸出格式
  輸出n!的準確值。
樣例輸入
10
樣例輸出
3628800

在前面大數乘法基礎上,我們添加了一個可以將數字轉換爲字符類型數組的函數,便於我們循環。

整個題就是進行n次大數乘法,很基礎。

當然,這道題不需要這麼麻煩的進行模擬。

最終代碼爲:

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAX 3000

using namespace std;

char beMultiplier[MAX]; //被乘數 
char multiplier[MAX];  //乘數 
int result[MAX];

int getCount(char a[]){
	int count = 0;
	for(int i=0;;i++)
		if(a[i]=='X') break;
		else count++;
	return count;
}

char  multiplication(char bemu[],char mu[]){ //大數相乘 
	int bCount = getCount(bemu);
	int mCount = getCount(mu);
	for(int i=mCount-1;i>=0;i--){ //從乘數最後一位開始乘 
		int nowx = mu[i]-'0';
		int spos = mCount - i - 1;
		int c = 0; //進位 
		int bpos = 0;
		for(int j=bCount-1;j>=0;j--){
			int nowy = bemu[j]-'0';
			int m = nowx*nowy; //乘積 
			int r = m%10; //餘數
			result[bpos+spos] += r;
			c = m/10; 
			result[bpos+spos+1] += c;
			if(result[bpos+spos]>=10){
				result[bpos+spos+1] += result[bpos+spos]/10;
				result[bpos+spos] = result[bpos+spos]%10;
			}
			bpos++;
		} 
	}
	int flag = 0,num=0;
	for(int i=MAX;i>=0;i--){ //獲取結果的位數 
		if(result[i]!=0) flag=1;
		if(flag) {
			num++;
		}
	}
	flag = 0;
	for(int i=MAX;i>=0;i--){  //將結果存儲在bemu數組中 
		if(result[i]!=0) flag=1;
		if(flag) {
			bemu[num-i-1] = result[i] +'0';
		}
	}
}

void set(char a[],int x){ //將數字存儲在數組中 
	int i=0,t=x;
	while(t>0){
		t/=10;
		i++;
	}
	while(x>0){
		int c = x%10;
		a[i-1] = c+'0';
		x /= 10;
		i--;
	}
}

int main()
{
	int n;
	cin>>n;
	memset(beMultiplier,'X',sizeof(beMultiplier));  //初始化被乘數數組 
	set(beMultiplier,1);
	for(int i=1;i<=n;i++){  //循環n次乘法 
		memset(result,0,sizeof(result));
		memset(multiplier,'X',sizeof(multiplier));
		set(multiplier,i); 
		
		multiplication(beMultiplier,multiplier);
	}
	for(int i=0;i<MAX;i++){  //輸出結果 
		if(beMultiplier[i]=='X') break;
		else cout<<beMultiplier[i];
	}
	cout<<endl;
	return 0;
}

代碼粗陋,還請海涵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章