给定两个以字符串形式表示的非负整数 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;
}
};