Leetcode-43: Multiply Strings

这题相当于实现BigInterger的乘法。不算难,但是调试也花了一些周折,还是要多练习。
需要注意的地方有:
1) “9133”×”0”=”0000”,要注意把开头的0去掉。
2) 以“123”×”456”为例,“123”相当于num1, “456”相当于num2。其中resStrs[0]=”00654”, //45600
resStrs[1]=”0219”, //9120
resStrs[2]=”8631” //1368
分别是45600,9120和1368的倒序。为什么要倒序呢,这里方便最后一位开始计算,要不然45600的最高位和9120与1368的最高位对不准。
3) 还要注意resStr[]后面都要添加相应多的’0’,以对应乘法的移位。
4) 最后的结果要reverse。
5) 要注意最后carry_count还要考虑。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

string multiply(string num1, string num2) {
    vector<string> resStrs(num1.size()); //(220, '');
    unsigned int carry_count=0;
    unsigned int result=0;

    for (int i=num1.size()-1; i>=0; --i) {
        carry_count=0;
        result=0;
        int digit1=num1.at(i)-'0';
        for (int j=num2.size()-1; j>=0; --j) {
            int digit2=num2.at(j)-'0';
            result=(digit1*digit2+carry_count)%10;
            carry_count = (digit1*digit2+carry_count)/10;
            resStrs[i]+=result+'0';
        }
        if (carry_count)
            resStrs[i]+=carry_count+'0';
        resStrs[i]=string(num1.size()-1-i, '0')+resStrs[i];   //add additional 0s
    }

    string resultStr;
    carry_count=0;
//cout<<resStrs[0]<<endl; //cout<<resStrs[1]<<endl; //cout<<resStrs[2]<<endl;
    for (int i=0; i<resStrs[0].size(); ++i ){   //from the 1-th digit to 10-th digit to 100-th digit to ...
        result=0;
        for (int j=0; j<num1.size(); ++j) {
            if (resStrs[j].size()>i)
                result+=resStrs[j].at(i)-'0';
        }
        resultStr+=(result+carry_count)%10+'0';
        carry_count=(result+carry_count)/10;
    }
    if (carry_count) resultStr+=carry_count+'0';

    reverse(resultStr.begin(), resultStr.end());
    size_t non_zero_pos=0;
    while(non_zero_pos<resultStr.size() && resultStr.at(non_zero_pos)=='0') non_zero_pos++;
    if (non_zero_pos == resultStr.size())
        return "0";
    else
        return resultStr.substr(non_zero_pos, resultStr.size()-non_zero_pos);
}

int main()
{
    string num1="9133";   //"123";
    string num2="0";  //"456";
    string result=multiply(num1, num2);
    cout<<result<<endl;

    return 0;
}

看了一下Leetcode网上的解法,有个解法很简洁

string multiply(string num1, string num2) {
    string sum(num1.size() + num2.size(), '0');

    for (int i = num1.size() - 1; 0 <= i; --i) {
        int carry = 0;
        for (int j = num2.size() - 1; 0 <= j; --j) {
            int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
            sum[i + j + 1] = tmp % 10 + '0';
            carry = tmp / 10;
        }
        sum[i] += carry;
    }

    size_t startpos = sum.find_first_not_of("0");
    if (string::npos != startpos) {
        return sum.substr(startpos);
    }
    return "0";
}

其中这两行

   int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
   sum[i + j + 1] = tmp % 10 + '0';

颇具功力。因为分析一下就可以发现,num1[i]*num2[j]和num1[j]*num2[i]的结果所存放的位置是一样的。
456
× 123
————
1368
9120
45600
————
56088

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值