[LeetCode]Multiply Strings

来源:互联网 发布:美国丽人 知乎 编辑:程序博客网 时间:2024/05/29 19:58

一、问题描述:

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.
  • Converting the input string to integer is NOT allowed.
  • You should NOT use internal library such as BigInteger.
二、问题分析:
题目就是模拟乘法操作,而且还是非负数,这样就比较简单了。
原本用了分治的方法去做,而且明显时间复杂度比模拟低,但竟然超时了......为了避免以后重复造轮子,这次把模拟乘法的代码贴出来。其中注释部分去掉之后为正负通用的乘法。
还有一个比较蛋疼的是命令行下to_string()总是找不到,干脆自己写一个好了(虽然这道题只是在调试的时候用了下...)
public:    string multiply(string num1, string num2) {    string ans(num1.length()+num2.length(), '0');    int PN = 1, n = ans.length();        if (num1.length()<1 || num2.length()<1) return ans;        if (num1 == "0" || num2 == "0") return "0";        // if (num1 == "-") {        // PN *= (-1);        // num1 = num1.substr(1, num1.length()-1);        // }        // if (num2 == "-") {        // PN *= (-1);        // num2 = num2.substr(1, num2.length()-1);        // }        for (int i = num1.length()-1; i >= 0; --i, --n) {        int carry = 0, pos = n-1;        for (int j = num2.length()-1; j >= 0; --j, --pos) {        int charMult = (num1[i]-'0')*(num2[j]-'0')+carry+ans[pos]-'0';        carry = charMult/10;        ans[pos] = charMult%10+'0';        }        while (carry) {        int charAdd = (ans[pos]-'0')+carry;        carry = charAdd/10;        ans[pos--] = charAdd%10+'0';        }        }        int i = 0;        for(; i<ans.length() && ans[i]=='0'; i++);        ans = ans.substr(i, ans.length()-i);        // if (PN == -1) ans = "-"+ans;        return ans;    }private:string to_string(int i) {stringstream ss;ss << i;string s;ss >> s;return s;}

==================================================================================================================
来来来,每次写高精度分治乘都是一趟血雨腥风。。。
C++版的来一发:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <string>#include <vector>#include <deque>#include <list>#include <set>#include <map>#include <stack>#include <queue>#include <numeric>#include <iomanip>#include <bitset>#include <sstream>#include <fstream>#define PI (acos(-1.0))#define EPS (1e-8)#define INF (1<<30)using namespace std;string add(string x, string y);string sub(string x, string y);string multiply(string x, string y);string to_string(int i) {stringstream ss;ss << i;string s;ss >> s;return s;}string add(string x, string y) {string s1(x);string s2(y);if (s1[0]=='-' && s2[0]!='-') return sub(s2, s1.substr(1));if (s1[0]!='-' && s2[0]=='-') return sub(s1, s2.substr(1));string sign;if (s1[0] == '-') {sign = "-";s1 = s1.substr(1);s2 = s2.substr(1);}else sign = "";while (s1[0] == '0') s1 = s1.substr(1);if (s1.length() == 0) s1 = "0";while (s2[0] == '0') s2 = s2.substr(1);if (s2.length() == 0) s2 = "0";string ans(max(s1.length(), s2.length())+1, '0');int s1_pos=s1.length()-1, s2_pos=s2.length()-1, carry=0, pos=ans.length()-1;for (; s1_pos>=0 && s2_pos>=0; s1_pos--, s2_pos--) {int val = s1[s1_pos]-'0'+s2[s2_pos]-'0'+carry;carry = val/10;ans[pos--] = val%10+'0';}while (s1_pos >= 0) {int val = s1[s1_pos--]-'0'+carry;carry = val/10;ans[pos--] = val%10+'0';}while (s2_pos >= 0) {int val = s2[s2_pos--]-'0'+carry;carry = val/10;ans[pos--] = val%10+'0';}if (carry)  ans[pos--] = '1';for (int i = 0; i <= ans.length(); ++i) {if (ans[i] != '0') {pos = i;break;}}// cout << "add: " << x << "," << y << endl;// cout << "add answer: " << sign+ans << endl;if (pos == ans.length()) return "0";return sign+ans.substr(pos);}string sub(string x, string y) {string s1(x);string s2(y);if (s1[0]=='-' && s2[0]!='-') return "-"+add(s2, s1.substr(1));if (s1[0]!='-' && s2[0]=='-') return "-"+add(s1, s2.substr(1));string sign;if (s1[0] == '-') {sign = "-";s1 = s1.substr(1);s2 = s2.substr(1);}else sign = "";while (s1[0] == '0') s1 = s1.substr(1);if (s1.length() == 0) s1 = "0";while (s2[0] == '0') s2 = s2.substr(1);if (s2.length() == 0) s2 = "0";if (s1.length()<s2.length() || (s1.length()==s2.length() && s1<s2)) {string tmp = s2;s2 = s1;s1 = tmp;if (sign.length() == 0) sign = "-";else sign = "";}string ans(s1.length()+1, '0');int s1_pos=s1.length()-1, s2_pos=s2.length()-1, carry=0, pos=ans.length()-1;for (; s1_pos>=0 && s2_pos>=0; s1_pos--, s2_pos--) {int val = (s1[s1_pos]-'0'+10)-(s2[s2_pos]-'0')-carry;if (val >= 10) {ans[pos--] = val%10+'0';carry = 0;}else {ans[pos--] = val+'0';carry = 1;}}while (s1_pos >= 0) {int val = s1[s1_pos--]-'0'+10-carry;if (val >= 10) {ans[pos--] = val%10+'0';carry = 0;}else {ans[pos--] = val+'0';carry = 1;}}for (int i = 0; i <= ans.length(); ++i) {if (ans[i] != '0') {pos = i;break;}}// cout << "sub: " << x << "," << y << endl;// cout << "sub answer: " << sign+ans << endl;if (pos == ans.length()) return "0";return sign+ans.substr(pos);}string multiply(string x, string y) {int sign = 1;string s1(x);string s2(y);if (s1=="0" || s2=="0") return "0";if (s1[0] == '-') {sign *= (-1);s1 = s1.substr(1);}if (s2[0] == '-') {sign *= (-1);s2 = s2.substr(1);}if (s1.length()==1 && s2.length()==1) {int res = (s1[0]-'0')*(s2[0]-'0');string ans = to_string(res);if (sign == -1) ans = "-"+ans;return ans;}int len = max(s1.length(), s2.length());while (s1.length() < len) s1 = "0"+s1;while (s2.length() < len) s2 = "0"+s2;string a = s1.substr(0, len/2);string b = s1.substr(len/2);string c = s2.substr(0, len/2);string d = s2.substr(len/2);string part1 = multiply(a, c);string part2 = multiply(b, d);// cout << "part1 = " << part1 << endl;// cout << "part2 = " << part2 << endl;string part3 = sub(a, b);string part4 = sub(d, c);// cout << "part3 = " << part3 << endl;// cout << "part4 = " << part4 << endl;string part5 = multiply(part3, part4);// cout << "part5 = " << part5 << endl;part3 = add(part5, part1);// cout << "part3 = " << part3 << endl;part3 = add(part3, part2);// cout << "part3 = " << part3 << endl;int add_zero = len-len/2;if (part1 != "0") for (int i = 0; i < add_zero*2; ++i) part1 = part1+"0";if (part3 != "0") for (int i = 0; i < add_zero; ++i) part3 = part3+"0";// cout << "part1 = " << part1 << endl;// cout << "part3 = " << part3 << endl;string ans = add(add(part1, part2), part3);// cout << "ans = " << ans << endl;int pos = 0;for (int i = 0; i <= ans.length(); ++i) {if (ans[i] != '0') {pos = i;break;}}if (sign == -1) ans = "-"+ans;// cout << "part: " << part1 << "," << part2 << "," << part3<< endl;// cout << "multiply: " << x << "," << y << endl;// cout << "multiply ans = " << ans << endl;return ans;}int main(int argc, char const *argv[]) {string s1, s2;while (cin >> s1 >> s2) {string result = multiply(s1, s2);cout << result << endl;}return 0;}




0 0
原创粉丝点击