长整数乘法
对于两个超过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
具体流程:
- 将两个长整数翻转并保存到两个数组中(假设其长度分别位n、m)。
- 构造一个(n+1) + (m+1)的数组用来保存其相乘结果。
- 将两个长整数单个位进行相乘并加上对应位置数然后存储(如上例中 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];
- 遍历整个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;
}