刷了150多道题,再来一发总结。再LeetCode中有一类题目,要求直接使用数字字符串进行运算,这类题目掌握技巧之后不容易出错,也比较简单,那么这篇博客将对这类题目进行总结,希望有所帮助。
小总结
这类题目需要注意两点:一点是进位检查,尤其是整个循环结束后,额外进行的进位检查,二是按位使用小整数运算,来直接操作字符串。
如果还有什么要注意的,就是某些情况下,在乘法时会出现开头为 ‘0’ 的数字字符串,这个时候增加一道过滤就可以了。
字符串加法
可以反序从最开始逐个相加,最后将结果反序,也可以直接从最末尾反向遍历进行操作。使用除法和取余操作来获取局部操作的结果。
字符串乘法
按照小学学的连乘法进行,这里需要注意一些技巧,如最后给出的代码中所指示的,可以一开始进行反序操作。
字符串乘法给了两份代码,第一份非常推荐,一开始就是直接产生N1+N2长度的字符串,在最后抹去最前面多余的0,这样操作效率很高。在按照连乘法进行连续的乘法加法,可以看走将一个 string x string 转化成了 char x char ,两个个位数乘法。分两层循环,在乘法过程中,每次乘法最多改变两位结果,高位采取进位模式保留。
代码
代码中有乘法和加法的操作。第一份代码为乘法,第二份代码其中调用了单独的加法子函数。
#include <iostream> #include <vector> #include <string> using namespace std; class Solution { public: string multiply(string num1, string num2) { int N1 = num1.size(); int N2 = num2.size(); if (N1 == 0 || N2 == 0) return ""; reverse(num1.begin(), num1.end()); reverse(num2.begin(), num2.end()); string ret(N1 + N2, '0'); for (int i = 0; i<N1; i++) { int carry = 0; int val = num1[i] - '0'; for (int j = 0; j<N2; j++) { carry += val * (num2[j] - '0') + (ret[i + j] - '0'); ret[i + j] = carry % 10 + '0'; carry = carry / 10; } if (carry != 0) ret[i + N2] = carry + '0'; } reverse(ret.begin(), ret.end()); int count = 0; while (count<(N1 + N2 - 1) && ret[count] == '0') { count++; } ret.erase(0, count); return ret; } string multiplyMy(string num1, string num2) { const int n1 = num1.size(); const int n2 = num2.size(); if (n1 == 0 || n2 == 0){ return string(""); } string res = "0"; string pot = ""; for (int i = n2 - 1; i >= 0; --i){ string tmp; tmp = mpy(num1, num2[i]); tmp = tmp + pot; res = add(res, tmp); pot += "0"; } return res; } private: string mpy(string num, char s){ string res; const int n = num.size(); int t = s - '0'; if (t == 0){ return string("0"); } int en = 0; char str[] = "0"; for (int i = n - 1; i >= 0; --i){ int tmp = num[i] - '0'; tmp = tmp * t + en; en = tmp / 10; str[0] = tmp % 10 + '0'; res = string(str) + res; } if (en){ str[0] = en + '0'; res = string(str) + res; } return res; } string add(string& num1, string& num2){ const int n1 = num1.size(); const int n2 = num2.size(); int i = n1, j = n2; int k = 0; string res; char str[] = "0"; while (i > 0 || j > 0) { i--; j--; if (i >= 0){ k += (num1[i] - '0'); } if (j >= 0){ k += (num2[j] - '0'); } str[0] = (k % 10 + '0'); res = string(str) + res; k = k / 10; } if (k){ str[0] = (k + '0'); res = string(str) + res; } res = res.erase(0, res.find_first_not_of("0")); if (res.empty()){ return string("0"); } return res; } }; int main(int argc, char *argv[]){ Solution s; cout << s.multiply("0", "52") << endl; system("pause"); return 0; }