快速提升代码能力(5)大数乘法string初始化

从零起步看算法(第五天 4.10)

//q7 A*B

本题重点:大数乘法

1.一开始以为和大数加法相似,最后发现有很多不同,就当练习大数加法了。

#include<stdio.h>
#include<string>
#include<cstring>
#include<iostream> 
#include<assert.h>
#include<cmath>
#include<algorithm>
using namespace std;
char sum[100000+5];

void mul(string s1,string s2,int len1,int len2){
	
	int len=0;//长度 
	int p=0;//进位 
	
	for(;len1>0||len2>0;len1--,len2--){
		
		if(len1>0&&len2>0){
			sum[len]=(((s1[len1]-'0')*(s2[len2]-'0')+p)%10)+'0';
			p=(((s1[len1]-'0')*(s2[len2]-'0')+p)/10);
		}
		
		else if(len1<=0){
			sum[len]=(((s2[len2]-'0')+p)%10)+'0';
			p=((s2[len2]-'0')+p)/10;
		}
		
		
		else{
			sum[len]=(((s1[len1]-'0')+p)%10)+'0';
			p=((s1[len1]-'0')+p)/10;
		}
		len++;
	}
	
	if(p>0)
	cout<<p+'0';
	for(int i=len-1;i>=0;i--){//末尾下标 
		cout<<sum[i];
	}
	
}
int main(){
	string s1,s2;
	cin>>s1;
	cin>>s2;
	int len1=s1.size();
	int len2=s2.size();
	mul(s1,s2,len1,len2);
	cout<<endl;
	
	return 0;
} 

2.学习优秀代码

(1).string s(s1+s2,'0');//string初始化

(2).s=s.substr(1.s.size()); //在串s中从位置为1,取到位置为s.size();

  (3).i*j      则乘积结果为m+n-1位(最高位无进位)或m+n位(最高位有进位)

#include<stdio.h>
#include<string>
#include<cstring>
#include<iostream> 
#include<assert.h>
#include<cmath>
#include<algorithm>
 using namespace std;  
 string BigNumMultiply(string str1,string str2)  
 {  
 int size1=str1.size(),size2=str2.size();  
 string str(size1+size2,'0');  
  for(int i=size2-1;i>=0;--i)  
{  
 int mulflag=0,addflag=0;  
 for(int j=size1-1;j>=0;--j)  
 {  
 int temp1=(str2[i]-'0')*(str1[j]-'0')+mulflag;  
 mulflag=temp1/10;  
 temp1=temp1%10;  
 int temp2=str[i+j+1]-'0'+temp1+addflag;  
 str[i+j+1]=temp2%10+48;  
addflag=temp2/10;  
}  
 str[i]+=mulflag+addflag;  
 }  
if(str[0]=='0')  
 str=str.substr(1,str.size());  
 return str;  
 }  
   
 int main()  
 {  
 string str1,str2;  

 while(cin>>str1>>str2)  
 {  
 if((str1[0]-'0')==0||(str2[0]-'0')==0) 
cout<<0<<endl;
 //cout<<str1<<"*"<<str2<<"="<<endl;  
else
 cout<<BigNumMultiply(str1,str2)<<endl;  
 }  
 return 0;  
 }  

3.最后贴上自己的代码

先加减,再进位的操作。

 #include<stdio.h>
#include<string>
#include<cstring>
#include<iostream> 
#include<assert.h>
#include<cmath>
#include<algorithm>
 using namespace std;
 string mul(string s1,string s2,int len1,int len2){
 	//先处理加法问题,再考虑进位问题 
 	string s(len1+len2,'0');
 	
 	for(int i=len1-1;i>=0;--i){
 		int adf=0;//加法进位 
 		int muf=0;//乘法进位 
 		
 		
 		
 		for(int j=len2-1;j>=0;--j){
 			
 			
 			
 			int temp1=(s1[i]-'0')*(s2[j]-'0')+muf;
 			muf=temp1/10;//进位 
 			temp1=temp1%10;//余数
			 
			 
			 
			 int temp2=s[i+j+1]-'0'+temp1+adf;//总数加减 
			 adf=temp2/10;
			 s[i+j+1]=temp2%10+'0';
 			
		 }
		 s[i]+=adf+muf;//进位 
	 }
	 if(s[0]==0)
	 s=s.substr(1,s.size()) ;
	 return s;
 } 
 
 int main(){
	string s1,s2;
	while(cin>>s1>>s2)
{

	int len1=s1.size();
	int len2=s2.size();
	if((s1[0]-'0'==0)||(s2[0]-'0'==0)){
		cout<<0<<endl;
	}
	else
	cout<<mul(s1,s2,len1,len2)<<endl;
	
}
	return 0;
} 

 

### 回答1: 好的,我来帮你写一段大数相乘的 C 语言代码。首先,我们需要定义一个结构体来存储大数。 ``` typedef struct { int num[1000]; // 存储数位 int len; // 数位长度 } bignum; ``` 然后,我们可以定义函数来进行大数相乘。 ``` bignum multiply(bignum a, bignum b) { bignum c; memset(c.num, 0, sizeof(c.num)); c.len = a.len + b.len; for (int i = 1; i <= a.len; i++) { for (int j = 1; j <= b.len; j++) { c.num[i+j-1] += a.num[i] * b.num[j]; c.num[i+j] += c.num[i+j-1] / 10; c.num[i+j-1] %= 10; } } while (c.len > 1 && c.num[c.len] == 0) c.len--; return c; } ``` 这段代码实现了大数相乘的基本过程,使用了模拟竖式乘法的方法。需要注意的是,在最后我们需要去除前导零。 希望这段代码能帮到你。 ### 回答2: 当然可以帮你写一段C语言的大数相乘代码。以下是一个简单的示例代码: ```c #include <stdio.h> #include <string.h> #define MAX_DIGITS 1000 // 最大位数 void multiply(char num1[], char num2[], char result[]) { int len1 = strlen(num1); int len2 = strlen(num2); int i, j, k; // 初始化结果数组为0 for (i = 0; i < MAX_DIGITS; i++) { result[i] = '0'; } // 逐位相乘,并将结果累加到结果数组 for (i = len2 - 1; i >= 0; i--) { int carry = 0; int n2 = num2[i] - '0'; for (j = len1 - 1; j >= 0; j--) { int n1 = num1[j] - '0'; int product = n1 * n2 + carry + (result[i + j + 1] - '0'); carry = product / 10; result[i + j + 1] = (product % 10) + '0'; } // 处理进位 result[i] = carry + '0'; } // 去除结果数组前面的0 int len = len1 + len2 - 1; while (result[len] == '0' && len > 0) { len--; } result[len + 1] = '\0'; // 翻转结果数组,得到最终结果 int left = 0, right = len; while (left < right) { char temp = result[left]; result[left] = result[right]; result[right] = temp; left++; right--; } } int main() { char num1[MAX_DIGITS], num2[MAX_DIGITS], result[MAX_DIGITS * 2]; // 输入要相乘的两个大数 printf("请输入第一个大数:"); scanf("%s", num1); printf("请输入第二个大数:"); scanf("%s", num2); // 调用大数相乘函数 multiply(num1, num2, result); // 输出结果 printf("相乘结果为:%s\n", result); return 0; } ``` 这段代码通过输入两个大数并调用`multiply`函数进行相乘运算,最终输出结果。请注意,这段代码只是简单示例,对于更大的数可能存在溢出或长度限制的问题,需要根据实际需求进行优化和处理。 ### 回答3: 当然可以帮您写一个C语言的大数相乘代码。下面是一个示例: ```c #include <stdio.h> #include <string.h> #include <stdlib.h> void multiply(char* num1, char* num2, char* result) { int len1 = strlen(num1); int len2 = strlen(num2); int len = len1 + len2; int* temp = (int*)malloc(len * sizeof(int)); // 初始化temp数组为0 memset(temp, 0, len * sizeof(int)); // 从低位到高位逐位相乘 for (int i = len1 - 1; i >= 0; i--) { for (int j = len2 - 1; j >= 0; j--) { int mul = (num1[i] - '0') * (num2[j] - '0'); int sum = temp[i + j + 1] + mul; temp[i + j] += sum / 10; // 进位 temp[i + j + 1] = sum % 10; // 当前位的值 } } // 转换为字符数组结果 int index = 0; while (index < len && temp[index] == 0) { index++; // 跳过前面的0 } if (index == len) { result[0] = '0'; result[1] = '\0'; return; } int i = 0; while (index < len) { result[i++] = temp[index++] + '0'; } result[i] = '\0'; free(temp); } int main() { char num1[100]; char num2[100]; char result[200]; printf("请输入第一个数: "); scanf("%s", num1); printf("请输入第二个数: "); scanf("%s", num2); multiply(num1, num2, result); printf("两个大数相乘的结果是: %s\n", result); return 0; } ``` 在这个示例代码中,我们定义了一个`multiply`函数,接受两个大数字符串`num1`和`num2`,并将结果以字符串形式保存在`result`中。代码使用了大数乘法的常用算法,逐位相乘并处理进位,最后将结果转换为字符数组形式。 在`main`函数中,我们通过用户输入两个大数,并输出它们相乘的结果。 需要注意的是,由于题目要求的是大数相乘,所以输入的数不能超过系统最大的整数(int)表示范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值