43. 字符串相乘

题目

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

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

示例 1:

cpp 复制代码
输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

cpp 复制代码
输入: num1 = "123", num2 = "456"
输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。

普通竖式法

思路

第一种方法的主要思路就是模拟我们平时手算的计算过程,其主要步骤如下:

  • 首先我们实现一个可以两个string类型可以相加的子函数。

  • 依次将每一个乘数与被乘数的结果相加就是最终结果。

  • 关键有两点:

    • 如果做string类型的乘法?

      其实我们每次的乘法都是单位数和(单位数或者多位数)相乘,那么我们可以把乘法看作是单位数次(多位数)相加。

    • 如何在乘数与被乘数的结果后面补充合适个数的零?

      乘数倒数第n位与被乘数的结果后面补充n-1个零。

AC代码

cpp 复制代码
class Solution {
public:
    string multiply(string num1, string num2) {
        if ("0" == num1 || "0" == num2){
            return "0";
        }
        string ret;
        int flag = 0;
        for (int i = num2.size() - 1; i >= 0; i--)
        {
            string tmp;
            int count = num2[i] - '0';
	        for (int j = 0; j < count; j++)
			{
				tmp = StringAdd(tmp, num1);
			}
            for (int k = 0; k < flag; k++)
            {
                tmp.push_back('0');
            }
            ret = StringAdd(ret, tmp);
            flag++;
        }
        return ret;
    }
    string StringAdd(string a, string b){
        int i = a.size() - 1;
        int j = b.size() - 1;
        string ret;
        int flag = 0;
        while (i >= 0 || j >= 0){
            int num1 = 0;
            if (i >= 0)
            {
                num1 = a[i] - '0';
                i--;
            }
            int num2 = 0;
            if (j >= 0)
            {
                num2 = b[j] - '0';
                j--;
            }
            int add = num1 + num2 + flag;
            if (add > 9)
            {
                flag = 1;
                add -= 10;
            }
            else
            {
                flag = 0;
            }
            ret.push_back('0' + add);
        }      
        if (1 == flag)
        {
            ret.push_back('1');
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }    
};

优化竖式法

思路

如果我们先不进位,最后一起进位的话就可以用一个整形数组暂时保存计算结果

  • 这个数组应该开辟多大的空间?

    如果m = num1.size() n = num2.size()

    假设num1长度是1,num2长度是1,那么最小长度为1,即为m+n-1;最大长度为2,即为m+n。

  • 如何在数组合适的位置加上计算结果?

    通过观察不难发现,被乘数的下标为i,乘数的下标为j,它们相乘的结果应该放在数组下标为i+j+1的位置。

AC代码

cpp 复制代码
class Solution {
public:
    string multiply(string num1, string num2) {
        if ("0" == num1 || "0" == num2)
        {
            return "0";
        }
        int sz_1 = num1.size();
        int sz_2 = num2.size();
        string ret;
        vector<int> v(sz_1+sz_2, 0);
        for (int i = num2.size() - 1; i >= 0; i--){
            int x2 = num2[i] - '0';
            for (int j = num1.size() - 1; j >= 0; j--){
                int x1 = num1[j] - '0';
                v[i+j+1] += x1 * x2;
            }
        }
        int flag = 0;
        for (int i = sz_1 + sz_2 - 1; i >= 0; i--){
            v[i] += flag;
            flag = v[i] / 10;
            v[i] %= 10;
        }
        if (v[0] != 0){
            ret.push_back('0' + v[0]);
        }
        for (int i = 1; i < sz_1 + sz_2; i++)
        {
            ret.push_back('0' + v[i]);
        }
        return ret;
    }
};
相关推荐
第九序言T5 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
ZhengEnCi6 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
龙亘川6 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人6 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
秋天的怀念_David6 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1007 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
Pniubi7 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_6187 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang7 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
专注仿真7 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法