问题描述: 

以字符串的形式读入两个数字,编写一个函数计算它们的乘积,以字符串形式返回。
数据范围: 读入的数字大小满足0n101000
要求:空间复杂度 O(n),时间复杂度 O(n2)

问题分析:两个数相乘可以拆成较小的一个数的每位与较大的数乘积,然后每个乘积的和就是
两数相乘的结果。所以我们需要解决的问题就拆分成了1、1位数与一个大数相乘;2、两个大
数相加的问题。
两个大数相加,字符串形式比较简单,主要就是注意进位问题。
然后就是一个个位数与一个大数相乘的问题。因为不确定乘积是几位数,每次的乘积都不同,
所以我们可以将末尾放在前面然后逐个加到字符串后面,最后反转所得到的字符串。
大数相加具体过程看函数sadds(),个位数与大数相乘可以看函数Pro();在需要注意的地方都
有相应的注释。代码中有个欲处理如果t的长度比s的长度大,那么就进行swap(s,t)操作,这样
是为了保证s在长度上是最大的,也能减少迭代次数,同时还能优化函数设计。
复杂度分析:假设s.size=m,t.size=n
时间复杂度O(n2):Pro函数为O(n),取决于m的大小;sadds()函数为O(n2),取决于m*n的大小。
空间复杂度O(n2):取决于m*n的大小。
class Solution {
public:
    string solve(string s, string t) {
        if(s.size()<t.size()) swap(s,t);
        if(t[0]=='0') return "0";
        int N=t.size();
        int M=s.size();
        string curZero="";//保存当前需要在得数后面添加0的个数
        string res="";//保存答案
        string cur;//当前乘积,t中每个数与s的乘积。
        for(int i=N-1;i>=0;--i) {
            if(t[i]=='0') cur="0";
            else cur=Pro(s,M,t[i]-'0')+curZero;//每次需要在后面添加0
            res=sadds(res,cur);
            curZero+="0";
        }
        return res;
    }
    string sadds(string res,string str2) {
        if(str2=="0") return res;
        if(res.size()<str2.size()) swap(res,str2);//保证res是最大长度的
        int k=0;//进位标志
        int x;//保存两个字符串每位相加的和,需加进位。从底到高
        int m=res.size()-1;
        int n=str2.size()-1;
        while(n>=0) {
            x=res[m]-'0'+str2[n]-'0'+k;
            res[m]=(x%10)+'0';
            k=x/10;
            --m,--n;
        }
        if(m==n&&k) {//当两个字符串长度相等时,需要考虑最后一次的进位
            res.insert(res.begin(),'1');
            return res;
        }
        while(m>=0&&k) {//较短字符串已经结束了,每次就看是否有进位
            x=res[m]-'0'+k;
            res[m]=(x%10)+'0';
            k=x/10;
            --m;
        }
        //如果上面一步一直到第一位,就需要看是否有进位
        if(m==-1&&k) res.insert(res.begin(),'1');
        return res;
    }
    string Pro(string s,int M,int x) {
//        if(x==0) return "0";//主函数已经考虑了t[i]==‘0’
        string m="";//保存当前乘积,是倒着的,方便操作
        int k=0;//进位标
        int mul=0;//x就是主函数t[i]的数字,保存每次x与s[j]的乘积
        for(int j=M-1;j>=0;--j) {
            mul=(s[j]-'0')*x+k;
            m+=((mul%10)+'0');
            k=mul/10;
        }
        if(k!=0) m+=(k+'0');//结束后需要看是否有进位
        reverse(m.begin(),m.end());//最后反转字符串就是当前乘积
        return m;
    }
};