前言
网上关于字符串加减乘除的整理并不全面,笔者参考多篇文章,优化后整理如下,字符串除法待更新。需注意:字符串加法和乘法使用通用解法。而字符串减法需考虑结果为负的特殊情况处理。
欢迎批评指正!
一、为什么需要用字符串做加减乘除?
当两个数非常大时,因为溢出问题,不能使用传统的加减乘除法,所以需要转换思路来处理。
二、 字符串运算
1. 字符串加法
string addstring(string s1, string s2) {
int i = s1.length() - 1;
int j = s2.length() - 1;
int add = 0;
string ss = "";
while (i >= 0 || j >= 0|| add != 0) {
if (i >= 0)
add = add + s1[i--] - '0';
if (j >= 0)
add = add + s2[j--] - '0';
ss = ss + to_string(add % 10);
add = add / 10;
}
reverse(ss.begin(), ss.end());
return ss;
}
2.字符串减法
字符串减法需考虑结果为负的特殊情况处理。
//大数减法
string sub(string s1,string s2){
bool minus = false;
if( s1.size() < s2.size() || ( s1.size() == s2.size() && s1 < s2 ) ){
swap(s1,s2);
minus = true;
}
int i = s1.size() - 1;
int j = s2.size() - 1;
int flag = 0;
string ans = "";
while( i >= 0 && j >= 0 ){
int tmp = 0;
if( s1[i] >= s2[j] ){
tmp = s1[i] - s2[j];
tmp = tmp - flag;
ans += to_string(tmp);
flag = 0;
}
else{
tmp = s1[i] - s2[j] + 10;
tmp = tmp - flag;
ans += to_string(tmp);
flag = 1;
}
i--;
j--;
}
// 处理较大数的剩余部分
while( i >= 0 ){
if(flag == 0){
ans += s1[i];
}
else{
int tmp = s1[i] - '0' - flag;
ans += to_string(tmp);
flag = 0;
}
i--;
}
// 翻转
reverse(ans.begin(),ans.end());
//去除前导 0
int k = 0;
while( k < ans.size() && ans[k] == '0') k++;
if( k == ans.size() ){
ans = "0";
}
else ans = ans.substr(k);
// 结果是否为负
return minus?"-" + ans:ans;
}
3.字符串乘法
来自LeetCode 43题
//使用大小为 n + m 的数组,num1的第i位乘以num2的第j位,结果
对应存放在数组的i+j+1的位置。
class Solution {
public:
string multiply(string num1, string num2) {
int n = num1.size();
int m = num2.size();
vector<int> result(n + m,0);
for(int i = n - 1; i >= 0; i--){
for(int j = m - 1;j >= 0; j--){
int tmp = (num1[i] - '0') * (num2[j] - '0');
tmp += result[i + j + 1];
result[i + j] += tmp / 10; //注意 这里是 +=
result[i + j + 1] = tmp % 10;
}
}
int i = 0;
while( i < n + m && result[i] == 0 ){
i++;
}
string ans;
for(; i < n + m; i++){
ans.push_back(result[i] + '0');
}
return ans.size() == 0?"0":ans;
}
};