43. 字符串相乘

题目

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

分析

1、去年10月份的时候的做法,涉及到了很多string的加法运算,由于每次string相加,都会涉及内存的分配与拷贝,效率很差。因此这次用数组保存中间计算结果,最后再用stringstream拼接到一起,效率会提升很多。
2、这里引用LeetCode评论区一位朋友的图。可见,我们可以把每一位的计算结果保存在数组里,最后遍历一遍数组,该进位的进位,该相加的相加。
3、用来保存结果的数组大小设置为多少好呢。做一个简单的证明:
(1)有两个待相乘的字符串 A A A B B B
(2)令 C = 1 0 B . l e n g t h ( ) C = 10^{B.length()} C=10B.length(),有 C . l e n g t h ( ) = B . l e n g t h ( ) + 1 C.length() = B.length() + 1 C.length()=B.length()+1
(3)则 ( A ∗ B ) . l e n g t h ( ) < = ( A ∗ C ) . l e n g t h ( ) = A . l e n g t h ( ) + B . l e n g t h ( ) (A * B).length() <= (A * C).length() = A.length() + B.length() (AB).length()<=(AC).length()=A.length()+B.length()
所以数组取两个字符串的长度和就够用了。

在这里插入图片描述

代码

class Solution {
public:
    int calStrMultiply(char c1, char c2) {
        return (c1 - '0') * (c2 - '0');
    }

    void joinStr(string& str, const vector<int>& arr) {
        stringstream ss;
        int index = arr.size() - 1;
        while (index > 0 && arr[index] == 0) {
            --index;
        }
        for (int i = index; i >= 0; --i) {
            ss << arr[i];
        }
        ss >> str;
    }

    string multiply(string num1, string num2) {
        num1 = string(num1.rbegin(), num1.rend());
        num2 = string(num2.rbegin(), num2.rend());
        
        vector<int> aux(num1.size() + num2.size(), 0);
        for (int i = num2.size() - 1; i >= 0; --i) {
            for (int j = num1.size() - 1; j >= 0; --j) {
                aux[i + j] += calStrMultiply(num1[j], num2[i]);
            }
        }

        int carry = 0;
        for (int i = 0; i < aux.size(); ++i) {
            int curSum = carry + aux[i];
            carry = curSum / 10;
            aux[i] = curSum % 10;
        }

        string res = "";
        joinStr(res, aux);
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值