原题链接:https://leetcode-cn.com/problems/multiply-strings/
题目
给定两个以字符串形式表示的非负整数 num1
和 num2
,返回 num1
和 num2
的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1
和num2
的长度小于110。num1
和num2
只包含数字 0-9。num1
和num2
均不以零开头,除非是数字 0 本身。- 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
分析
两数相乘,假设A有n1位,B有n2位,则乘积结果为n1+n2-1位(最高位无进位)或n1+n2位(最高位有进位),即相乘的结果最多有n1+n2位。
以123与45相乘为例,计算过程实际为错位相乘相加,第2个数的每一位依次与第1个数的每一位错位相乘,再将相乘的结果相加,编程实现就是使用两层for循环,这里使用一个数组来存放最终的字符串形式的结果,在for循环的每一次计算中,都会更新结果数组中的两位,一位是当前计算位,它是某两位置相乘加上本位之前的结果再对10取余,另一位是该结果的进位制,累加到前一位,用于下次计算。
1 2 3
X 4 5
----------
1 5 → 0 0 0 1 5
1 0 → 0 0 1 1 5
0 5 → 0 0 6 1 5
--------
1 2 → 0 0 7 3 5
0 8 → 0 1 5 3 5
0 4 → 0 5 5 1 5
----------
0 5 5 3 5
↑ ↑ ↑ ↑ ↑
0 1 2 3 4 ← index
C++实现
class Solution
{
public:
string multiply(string num1, string num2)
{
int n1=num1.size();// c++中的size()和length()没有区别,length()是C语言保留下来的
int n2=num2.size();
// A的位数为n1,B的位数为n2,则乘积结果为n1+n2-1位(最高位无进位)或n1+n2位(最高位有进位)
string res(n1+n2,'0');
// 从低位开始相乘
for(int i=n2-1;i>=0;i--)
{
for(int j=n1-1;j>=0;j--)
{
int temp=(res[i+j+1]-'0')+(num1[j]-'0')*(num2[i]-'0');// 上次该位的结果+两数相乘的结果
res[i+j+1]=temp%10+'0';// 当前位赋值(需加'0')(该位最终结果或用于下次计算)
res[i+j]+=temp/10; // 将进位值累加到前一位,res[i+j]已经初始化为'0',只需直接加上int类型
}
}
// 去除首位'0'
for(int i=0;i<n1+n2;i++)
{
if(res[i]!='0')
return res.substr(i);
}
return "0";
}
};
运行结果
输入
"123"
"45"
输出
"5535"