【Leetcode】【字符串相乘】

43. 字符串相乘

 

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

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/multiply-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

对于字符串相乘,我们先需要定义字符串相加。 

public:
    string addStrings(string num1, string num2) {
//分别获取两个字符串的数组的最大下标
        int end1=num1.size()-1,end2=num2.size()-1;
//用next来存储进位
        int next=0;
//创建存储结果的字符串
        string strRet;
//只要有一个字符串中还有数据就要继续循环
        while(end1>=0 || end2>=0)
        {
//如果读取到的非空的话,就将字符串转换为数值
            int val1=end1>=0 ?num1[end1]-'0' :0;
            int val2=end2>=0 ?num2[end2]-'0' :0;
 
            int ret=val1+val2+next;
//进位最多也只是9+9,最大也仅仅是1
            next=ret>9 ? 1:0;
//可以采用insert指定在0号位置,插入一个元素,然后将我们计算过后的结果转换为字符串传入
            // strRet.insert(0,1,(ret%10)+‘0’);
//或者是使用迭代器,将迭代器的开始位置传入,然后将我们计算过后的结果转换为字符串传入
            strRet.insert(strRet.begin(),'0'+(ret%10));
//循环迭代
            --end1;
            --end2;
        }
        //处理1+9之类的情况,如果尾部为0,而十位上的读取都已经没有数据了,
        //但是还有进位的话就需要再头插1
        if(next)
        {
            strRet.insert(strRet.begin(),'1');
        }
        return strRet;
    }

 字符串相加还可以采用更加高效的尾插法

public:
    string addStrings(string num1, string num2) {
        int end1=num1.size()-1,end2=num2.size()-1;
        int next=0;
        string strRet;
        while(end1>=0 || end2>=0)
        {
            int val1=end1>=0 ?num1[end1]-'0' :0;
            int val2=end2>=0 ?num2[end2]-'0' :0;
            int ret=val1+val2+next;
            next=ret>9 ? 1:0;

            //尾插
            strRet+=('0'+ ret%10);

            --end1;
            --end2;
        }
        //如果next还有进位就需要再尾插1
        if(next==1)
        {
            strRet+='1';
        }

        //逆置
        reverse(strRet.begin(),strRet.end());
        return strRet;
    }

 然后编写字符串相乘的函数。字符串相乘的函数需要调用我们字符串相加的函数。

class Solution {

public:
    string multiply(string num1, string num2) {
//如果两个数都是0就直接返回
        if (num1 == "0" || num2 == "0") {
            return "0";
        }
//ans中存储着我们的结果
        string ans = "0";
        int m = num1.size(), n = num2.size();
//从其中一个字符串的个位开始逐个向前遍历
//这里需要注意的是字符串的个位是size()-1的位置,而不是0!!!!
        for (int i = n - 1; i >= 0; i--) {
//创建临时字符串存储我们本次相加的结果
            string curr;
//add是用来存储进位的
            int add = 0;
//我们需要判断我们所取出的这个数的位数,然后尾插0来补足位数
            for (int j = n - 1; j > i; j--) {
                curr.push_back(0);
            }
//注意在运算的时候需要-'0'
            int y = num2.at(i) - '0';
//从个位到高位遍历另外一个字符串。
            for (int j = m - 1; j >= 0; j--) {
                int x = num1.at(j) - '0';
//不要忘了加上进位
                int product = x * y + add;
//这里我们采用的是尾插,不要忘了最后要把数据反转回来
                curr.push_back(product % 10);
//计算出我们的进位
                add = product / 10;
            }
//如果两个字符串都计算完了,但是还有进位的话,我们还需要将这个进位尾插到我们的结果字符串中
            while (add != 0) {
                curr.push_back(add % 10);
                add /= 10;
            }
//由于我们采用的是尾插,也就是说高位被放在了后面,所以要反转
            reverse(curr.begin(), curr.end());
            for (auto &c : curr) {
//不要忘了将插入的每一个字符都加上'0'
                c += '0';
            }
//调用我们的字符串加法,将我们的本次计算出来的数据相加到最终的结果中
            ans = addStrings(ans, curr);
        }
        return ans;
    }
public:
    string addStrings(string num1, string num2) {
        int end1=num1.size()-1,end2=num2.size()-1;
        int next=0;
        string strRet;
        while(end1>=0 || end2>=0)
        {
            int val1=end1>=0 ?num1[end1]-'0' :0;
            int val2=end2>=0 ?num2[end2]-'0' :0;
            int ret=val1+val2+next;
            next=ret>9 ? 1:0;

            //尾插
            strRet+=('0'+ ret%10);

            --end1;
            --end2;
        }
        //如果next还有进位就需要再尾插1
        if(next==1)
        {
            strRet+='1';
        }

        //逆置
        reverse(strRet.begin(),strRet.end());
        return strRet;
    }

};

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桜キャンドル淵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值