试题 算法训练 P0805
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过10位,然后把它们相乘的结果存储在另一个字符串当中(长度不会超过20位),最后把这个字符串打印出来。例如,假设用户输入为:62773417和12345678,则输出结果为:774980393241726.
编写函数 void Multiply(char* s1, char* s2, char* result); 实现大数乘法(只考虑正整数),其中result = s1 * s2.
编写main函数测试该函数的正确性.
输入:
62773417 12345678
输出:
774980393241726
思路:模拟竖式运算
1、数字通过字符串形式输入存储
2、将字符串形式转为字符类型的数字
3、倒序(因为左边是高位,右边是低位;需要把低位放到左边)
4、通过两个循环实现第一个数的每一位都与第二个数的每一位进行相乘。
如何将相乘的结果存储起来呢?我们通过观察可以得知:如果乘数为A和B,A的位数为m,B的位数为n,则乘积结果为m+n-1位(最高位无进位)或m+n位(最高位有进位)。因此可以分配一个m+n的数组来存储最终结果。
5、考虑进位
6、倒序输出数组即可
下面是模拟123*45的思路过程:
以下是AC代码:
(可通过注释理解代码)
#include<iostream>
#include<cstring>
using namespace std;
int a[20],b[20],c[40];
//a、b数组存储输入的字符串类型转换
//c是存储结果的数组
void Multiply(string s1, string s2)
{
string result;//存储结果字符串
//长度记录
int len1 = s1.length();
int len2 = s2.length();
int len = len1 + len2;
//将输入的字符串倒序并转换成int类型存储到a、b两个数组中
for(int j = 0; j < len1; j++)
a[j] = s1[len1 - j - 1] - '0';
for(int j = 0; j < len2; j++)
b[j] = s2[len2 - j - 1] - '0';
//实现第一个数的每一位都与第二个数的每一位相乘
//把结果存储到数组c中,存储位置为i+j
for(int i = 0;i < len1;i ++)
{
for(int j = 0;j < len2;j ++)
c[i + j] += a[i] * b[j];//可根据上图模拟思考为什么
}
//考虑进位
for(int i = 0;i < len;i ++)
{
if(c[i] > 9) //如果是两位数要进位
{
c[i + 1] += c[i] / 10;//进位到下一位
c[i] %= 10;//取个位作为本位
}
}
//判断最高位是否为0,为0就去掉(len-1)
if(c[len- 1] == 0 && len > 1) len --;
//因为输入的字符串被倒序
//输出的结果也要倒序输出,才是正确答案
for(int j = 0;j != len;j ++)
{
//cout<<c[len-j-1];//输出可以直接用数组输出
/* result[j] = c[len - j - 1] + '0';如果要通过字符串输出就使用这条
cout<< result[j];*/
}
}
int main()
{
string a,b;
cin>>a>>b;
Multiply(a,b);
return 0;
}