C++ || 长整数相乘

长整数乘法

对于两个超过long long范围的整数, 我们无法通过整型变量去保存它们,当然就更无法直接使其相乘去得到结果。通常我们使用字符串保存两个长整数及其相乘结果。

思路:

对两个长整数单个位进行相乘然后直接存入数组中对应位置,等全部运算结束后,再遍历整个数组进行进位操作。如下示例:

  • 对于两个数如 99 * 99,分解其运算过程如下:
  		9   9
  		9   9
  ----------------
  		81  81
    81  81
  -----------------
   81  162  81 (处理进位)
   81  170	1
   98   0   1
--------------------
9   8   0   1 

具体流程:

  1. 将两个长整数翻转并保存到两个数组中(假设其长度分别位n、m)。
  2. 构造一个(n+1) + (m+1)的数组用来保存其相乘结果。
  3. 将两个长整数单个位进行相乘并加上对应位置数然后存储(如上例中 81 + 81 = 162 )。相乘的对应位置规则如下:
    • v1[0] * v2[0] ,对应存储位置:res[0 + 0]。
    • v1[0] * v2[1] ,对应存储位置:res[0 + 1]。
    • v1[i] * v2[j] , 对应存储位置: res[i + j]。
      即:res[i + j] = res[i + j] + v1[i] * v2[j];
  4. 遍历整个res数组进行进位操作。

实现代码:

string multiply(string str1, string str2)
{
	if (str1.empty() || str2.empty())
		return "";

	vector<int> vec1(str1.length(), 0);
	vector<int> vec2(str2.length(), 0);
	
	//将两个长整数翻转保存在数组中
	for (size_t i = 0; i < str1.length(); ++i)
		vec1[str1.length() - 1 - i] = str1[i] - '0';
	for (size_t i = 0; i < str2.length(); ++i)
		vec2[str2.length() - 1 - i] = str2[i] - '0';
		
	//构造一个(n+1) + (m+1)的数组用来保存其相乘结果。
	int n = vec1.size() + 1 + vec2.size() + 1;
	vector<int> res(n, 0);
	
	//将两个长整数单个位进行相乘并加上对应位置数然后存储
	for (size_t i = 0; i < vec1.size(); ++i) {
		for (size_t j = 0; j < vec2.size(); ++j) {
			res[i + j] = res[i + j] + vec1[i] * vec2[j];
		}
	}
	
	//遍历整个res数组进行进位操作。
	int carry = 0; //进位
	for (size_t i = 0; i < n; ++i)
	{
		int temp = res[i] +  carry;
		res[i] = temp % 10;
		carry = temp / 10;
	}

	//去掉多余的0然后转为字符串存储
	string ret;
	while (n-- > 0) {
		if (res[n] != 0)
			break;
	}

	while (n >= 0) {
		char ch = res[n--] + '0';
		ret.push_back(ch);
	}

	if (ret.empty())
		ret = "0";

	return ret;
}

当然,也可以在相乘过程中处理进位,代码如下:

string multiply(string str1, string str2)
{
	if (str1.empty() || str2.empty())
		return "";

	vector<int> vec1(str1.length(), 0);
	vector<int> vec2(str2.length(), 0);
	
	//将两个长整数翻转保存在数组中
	for (size_t i = 0; i < str1.length(); ++i)
		vec1[str1.length() - 1 - i] = str1[i] - '0';
	for (size_t i = 0; i < str2.length(); ++i)
		vec2[str2.length() - 1 - i] = str2[i] - '0';
		
	//构造一个(n+1) + (m+1)的数组用来保存其相乘结果。
	int n = vec1.size() + 1 + vec2.size() + 1;
	vector<int> res(n, 0);
	
	//长整数相乘
	for (size_t i = 0; i < vec1.size(); ++i) {
		for (size_t j = 0; j < vec2.size(); ++j) {
			int temp = vec1[i] * vec2[j] + res[i + j];
			res[i + j] = temp % 10;
			int carry = temp / 10;

			size_t k = i + j + 1;
			while (carry != 0) {
				res[k] = res[k] + carry % 10;
				carry /= 10;
				++k;
			}
		}
	}
	
	//去掉多余的0然后转为字符串存储
	string ret;
	while (n-- > 0) {
		if (res[n] != 0)
			break;
	}

	while (n >= 0) {
		char ch = res[n--] + '0';
		ret.push_back(ch);
	}

	if (ret.empty())
		ret = "0";

	return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值