给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
方法1:用字符串的解法,从低位开始对应相加,然后设置一个carry变量表示进位。每次得到的插入到现在结果开头就可以了。
class Solution {
public:
string addStrings(string num1, string num2) {
if(!num1.size() || !num2.size()){
return num1 == "" ? num2:num1;
}
int i = num1.size()-1,j = num2.size()-1;
int carry = 0;
string res;
while(i >=0 || j >=0){
int number1 = i >=0 ? num1[i] - '0' : 0;
int number2 = j >=0 ? num2[j] - '0' : 0;
int sum = number1 + number2 + carry;
res.insert(res.begin(),sum % 10 + '0');
carry = sum / 10;
i--;j--;
}
//小心可能最后还有进位:'1' + '9'
return carry == 1 ? '1'+res : res;
}
};
方法2:使用数组。首先把每一位对应相加,然后从后向前遍历,把进位的累加到前一位就可以了。如果字符串str1长度为m,str2长度为n,那么存储结果的数组长度为max(m,n) + 1,因为还可能存在一位进位。不过这种题目会告诉你字符串最大长度。
直接开辟最大长度空间+1就可以了。
题目要求:
num1 和num2 的长度都小于 5100.
num1 和num2 都只包含数字 0-9.
num1 和num2 都不包含任何前导零。
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
class Solution {
public:
string addStrings(string num1, string num2) {
if(!num1.size() || !num2.size()) return "";
if(num1 == "0" || num2 == "0") return num1 == "0" ? num2:num1;
int n1[5100];
int n2[5100];
int sum[5100];
string res;
int max_len = 5100;
for(int i = 0;i<max_len;i++){
n1[i] = 0;
n2[i] = 0;
sum[i] = 0;
}
sum[max_len-1] = 0;
//字符串的后面拷贝到数组的最后,所以要保存数组最后的位置递减
int m = max_len-1,n = max_len-1;
for(int i = num1.size()-1;i>=0;i--){
n1[m--] = num1[i]-'0';
}
for(int i = num2.size()-1;i>=0;i--){
n2[n--] = num2[i]-'0';
}
for(int i = max_len-1;i>=0;i--){
sum[i] = n1[i] + n2[i];
}
for(int i = max_len-1;i>0;i--){
int carry = sum[i] / 10;
sum[i-1] += carry;
sum[i] %= 10;
}
int t = 0;
while(t<= max_len-1 && sum[t] == 0) t++;
while(t<= max_len-1) res += sum[t++]+'0';
return res;
}
};
总结:用数组的解法。首先两个数字字符串n1,n2相乘,得到结果最长为(n1+n2)位。开辟一个这样长度的数组记为:result
最重要的问题:字符串str1的第i位,和字符串str2的第j位相乘之后,得到的结果放在result的哪一位?
当6(第1位)X9((第1位)时,结果54在result的第3位。
当6(第1位)X8((第0位)时,结果48在result的第2位。
当7(第0位)X9((第1位)时,结果63在result的第2位。
当7(第0位)X8((第0位)时,结果54在result的第1位。
归纳出结论str[i]乘以str[j]的结构放在result[i+j+1]。
一些边界条件还是要注意,比如字符串为空;字符串是“0”;另外最终结果在输出的时候也要注意把前面的0给略过。
class Solution {
public:
string multiply(string num1, string num2) {
if(!num1.size()|| !num2.size()) return "";
if(num1 == "0" || num2 == "0") return "0";
int len1 = num1.size(),len2 =num2.size();
vector<int> sum(len1+len2,0);
string res;
for(int i = len1-1;i>=0;i--){
for(int j = len2-1;j>=0;j--){
sum[i+j+1] += (num1[i]-'0') * (num2[j]-'0');
}
}
for(int n = len1+len2-1;n>0;n--){
int carry = sum[n] /10;
sum[n-1] += carry ;
sum[n] %= 10;
}
int t = 0;
while(t <= len1 + len2-1 && sum[t] == 0) t++;
while(t <= len1+len2-1){
res += sum[t] + '0';
t++;
}
return res;
}
};