过去会遗忘,现在不会

字符串相乘

给定两个字符串,长度在[1,200]这个区间

字符串只有数字,求它们的乘积并返回结果的字符串。不准使用内置函数。

 

 

一开始想的是直接循环相加,毕竟乘积的本质也是累加,加法也更容易实现。

后来发现数字太大的话(比如150位),根本没办法循环相加,就很蠢。

 

于是直接乘。乘法原理上过小学的都知道。

说下算法实现。

首先给定的字符串肯定要变成数字,用两个数组表示(且数字逆序,比如字符串123456 数组就是654321 )。

既然要乘,还得有一个存答案的数组。这个数组长度肯定不超过前面两个数组长度的总和(乘法性质)。

剩下就是一一对应相乘。(因为是逆序,所以是从个位开始相乘,满足乘法的要求)。

 

解释一下,123*456,变成竖式,是不是 123*6,123*50,123*400;

仔细看对位,

个位*个位,答案在个位,(有进位不管,先看成整体),

十位*个位 答案在十位

百位*个位 答案在百位

百位*百位 答案在 十万位

这和数组下标不正好对应上吗?

0位置*0位置对应 0位

1位置*0位置对应1位

2位置*0位置对应2位置

3位置*3位置对应6位置

很明显了 ,所以最终存储答案的那个数组,每个位置对应的数就有了。

问题是,这些数是可能大于等于10的。

因此需要进位操作。这是一个简单的循环累加过程。

进位完,得到一个逆序的答案。

反转数组,就是正序。

数组初始长度为m+n,但是答案位数不一定是。

所以要检测反转后的数组第一个不为零的数的位置。

从这个位置开始,一一把数变成字符整合成一个字符串,就是最终答案。

代码如下

class Solution {
public:


    string multiply(string num1, string num2) {
vector<int> n1,n2;
vector<int> re_ans(num1.size()+num2.size(),0);
string ans;
if(num1=="0"||num2=="0") return "0";

for(int i=num1.size()-1;i>=0;i--)
{
    n1.push_back(num1[i]-'0');
}

for(int i=num2.size()-1;i>=0;i--)
{
 n2.push_back(num2[i]-'0');
}
int yu=0;
int jw=0;
for(int i=0;i<n1.size();i++)
{
    for(int j=0;j<n2.size();j++)
    {
        re_ans[i+j]+=n1[i]*n2[j];
    }
}
for(int i=0;i<re_ans.size();i++)
{
    re_ans[i]+=jw;
    if(re_ans[i]>9)
    {
        jw=re_ans[i]/10;
        yu=re_ans[i]%10;
        re_ans[i]=yu;
    }
    else jw=0;
}
reverse(re_ans.begin(),re_ans.end());
int begin=0;
for(int i=0;i<re_ans.size();i++)
{
if(re_ans[i]!=0){
    begin=i;break;
} 
}

for(int i=begin;i<re_ans.size();i++)
{
    ans+=re_ans[i]+'0';
}


return ans;

    }
};

 

posted on 2023-06-27 15:17  WhatAnyWay  阅读(219)  评论(0)    收藏  举报