动态数组vector解决高精度乘法问题(仅限整数)

 

在遇到大数相乘时,会出现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;
}

 

 

 

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值