在遇到大数相乘时,会出现int、long int、long long 都溢出的情况,这时候可以用数组来进行进位运算,并存储计算结果
总体思路:
两个数a与b相乘,通过模、除运算将a的个十百等位分开存储在vector中,运用for_each函数将各个位同时乘以b,再从个位逐次运用模、除运算,以达成进位的效果,最后输出结果
实现步骤:
1、确定容器的位数
在用纸笔运算时,我们向最高位进位,默认高位原本为0,加上进位数得到高位数。如,8*9,8与9最高位是个位,结果为72,最高位是十位,7实际上由十位原本的0加上个位进位的7相加而成
即0|8*0|9=0|72=>7|2(|表示十位和个位的分界线)
写代码时,要让“高位”元素初值为0,这样才能进位(不然,未定义初值的元素值不确定)
因此需要确定最高位的位数。n位数*m位数,结果应在n+m~n+m-1位数之间。首先确定结果长度,代码如下:
string A = to_string(a);
string B = to_string(b);
int A1 = A.length();
int B1 = B.length();
//或者用<cmath>内置函数log10()来计算长度
//int A1 = log10(a)+1;
//int B1 = log10(b)+1;
vector<long long> numbers(A1 + B1, 0);
2、进位
由于输出时先输出高位,所以将vector末尾定为个位,逐次向前进位
int i = A1 + B1-1;
numbers[i] = a;
//vector最后一位为个位a
while (numbers[i] != 0)
{
long long k = numbers[i] / 10;
numbers[i] = numbers[i] % 10;//个位为a的个位
numbers[i - 1] = k;//从个位溢出的位数加在十位
i--;
}
3、对vector每个元素乘以b
用for_each()来进行,之前文章提到过for_each()的用法
for_each(numbers.begin(), numbers.end(), [b](long long& n)mutable {n = n * b; });
4、进位
与[2]一样
5、判断最高位是否为0
if (numbers[0] == 0)
{
numbers.erase(numbers.begin());
}
6、输出
for (int n : numbers)
{
cout<<n;
}
完整代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<sstream>
using namespace std;
void multiply(long long a, long long b)
{
string A = to_string(a);
string B = to_string(b);
int A1 = A.length();
int B1 = B.length();
vector<long long> numbers(A1 + B1, 0);
int i = A1 + B1-1;
numbers[i] = a;
while (numbers[i] != 0)
{
long long k = numbers[i] / 10;
numbers[i] = numbers[i] % 10;
numbers[i - 1] = k;
i--;
}
for_each(numbers.begin(), numbers.end(), [b](long long& n)mutable {n = n * b; });
i = A1 + B1 - 1;
while(i!=0)
{
long long k = numbers[i] / 10;
numbers[i] = numbers[i] % 10;
numbers[i - 1] += k;
i--;
}
if (numbers[0] == 0)
{
numbers.erase(numbers.begin());
}
for (int n : numbers)
{
cout<<n;
}
cout << endl;
}
int main()
{
long long a, b;
cin >> a >> b;
multiply(a, b);
return 0;
}
515

被折叠的 条评论
为什么被折叠?



