leetcode 第42题 Multiply Strings
题目:Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
就是实现大数乘法。嘿嘿,我先用long long直接乘试试手感,试过了不行。所以还是要用字符串表示才行。
我是这样做的,先实现两个子函数,一个是实现一个数和一个字符串的数相乘的结果。另一个是实现两个字符串相加的结果。这样,大数乘法就可以由其中一个大数的每一位和另一个大数相乘然后再相加,就是要注意分解一个大数的时候记得要在结果后面加上零。例如12乘以3,我们把12分成1和2分别和3相乘,然后1和3相乘的后面要加一个零,因为1处于12的十位数。
oj上居然用了148ms。不忍直视啊。写了那么长。。。虽然Accept了
class Solution { public: string singleMulti(string s, char a) // 给定一个字符串和一个字符,返回乘积(字符串形式) { if (s.size() == 0) return s; if (a == '0') return "0"; int c = a - '0'; int up = 0; for (int i = s.size() - 1; i > -1; --i) { int tmp = s[i] - '0'; int sum_now = up + c*tmp; s[i] = sum_now%10 + '0'; up = sum_now/10; } if (up != 0) {char tmp = up + '0'; s = tmp + s;} return s; } string sum42(string s1, string s2) // sum of two string { if (s1.size() == 0) return s2; if (s2.size() == 0) return s1; string s = s1; int len1 = s1.size() - 1, len2 = s2.size() - 1, up = 0; while(len1 > -1 && len2 > -1) { int n1 = s1[len1] - '0'; int n2 = s2[len2] - '0'; int n3 = n1 + n2 + up; s[len1] = n3%10 + '0'; up = n3/10; len1--;len2--; } while(len1 > -1) { int n1 = s1[len1] - '0'; int n3 = n1 + up; s[len1] = n3%10 + '0'; up = n3/10; len1--; } while(len2 > -1) { int n2 = s2[len2] - '0'; int n3 = n2 + up; char tmp = n3%10 + '0'; s = tmp + s; up = n3/10; len2--; } if(up) { char tmp = up + '0'; s = tmp + s; } return s; } string multiply(string num1, string num2) { if (num1 == "0" || num2 == "0") return "0"; int len1 = num1.size()-1; string s; int cnt = 0; while(len1 > -1) { string tmp = ""; int tn = cnt; while(tn) { tmp = '0' + tmp; tn--; } s = sum42(s,singleMulti(num2, num1[len1])+ tmp); len1--; cnt++; } return s; } };
由于自己的代码那么长,所以也学习了下别人的,例如这里利用下面的图,很好理解。将图贴出:
我们以289*758为例
按照这个图我写了下代码(跟原版主略有不同):
class Solution { public: string multiply(string num1, string num2) { if (num1 == "0" || num2 == "0") return "0"; string s = ""; int len1 = num1.size(), len2 = num2.size(); vector<int> container(len1+len2, 0); // 用来存表中红色部分值 for (int i = 0; i < len1; ++i) for (int j = 0; j < len2; ++j) { container[i+j] += (num1[len1 - 1 - i]-'0')*(num2[len2 - 1 - j]-'0'); // 注意标号 } //处理进位 int up = 0, cnt = 0; while(cnt<len1+len2) { container[cnt] += up; up = container[cnt]/10; container[cnt] %= 10; cnt++; } cnt--; while(cnt > -1 && !container[cnt])//不应该有的零去掉 { cnt--; }; while(cnt > -1) // 输出就是结果,注意方向被搞反了 { char ch = container[cnt] + '0'; s += ch; cnt--; } return s; } };
这个主要是注意存的方向,不要把小标弄混淆了。输出的时候也要注意,别搞反了。低于60ms过。