【leetcode】43. Multiply Strings(大数相乘)
Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. Note: You must not use any built-in BigInteger library or convert the inputs to integer directly.
暴力法 转换为数值型变量再进行相乘 但是对于大数会溢出
class Solution { public: string multiply(string num1, string num2) { if(num1=="0" || num2=="0") return "0"; long long num1_=sstonum(num1); long long num2_=sstonum(num2); long long result=num1_*num2_; return numtoss(result); } long long sstonum(string num){ long long res=0; for(char nn:num){ res=res*10+(nn-'0'); } return res; } string numtoss(long long num){ stack<char>dp; string res; while(num>0){ dp.push(num%10+'0'); num=num/10; } while(dp.size()>0){ res+=dp.top(); dp.pop(); } return res; } };
只要涉及数值运算 都会溢出 那咋办呢?
一位一位的乘了再加起来 这道题让我们求两个字符串数字的相乘,输入的两个数和返回的数都是以字符串格式储存的,这样做的原因可能是这样可以计算超大数相乘,可以不受 int 或 long 的数值范围的约束,那么该如何来计算乘法呢,小时候都学过多位数的乘法过程,都是每位相乘然后错位相加,那么这里就是用到这种方法,举个例子,比如 89 x 76,那么根据小学的算术知识,不难写出计算过程如下:
8 9 <- num2 7 6 <- num1 ------- 5 4 4 8 6 3 5 6 ------- 6 7 6 4
如果自己再写些例子出来,不难发现,两数相乘得到的乘积的长度其实其实不会超过两个数字的长度之和,若 num1 长度为m,num2 长度为n,则 num1 x num2 的长度不会超过 m+n,还有就是要明白乘的时候为什么要错位,比如6乘8得到的 48 为啥要跟6乘9得到的 54 错位相加,因为8是十位上的数字,其本身相当于80,所以错开的一位实际上末尾需要补的0。还有一点需要观察出来的就是,num1 和 num2 中任意位置的两个数字相乘,得到的两位数在最终结果中的位置是确定的,比如 num1 中位置为i的数字乘以 num2 中位置为j的数字,那么得到的两位数字的位置为 i+j 和 i+j+1,明白了这些后,就可以进行错位相加了,累加出最终的结果。
由于要从个位上开始相乘,所以从 num1 和 num2 字符串的尾部开始往前遍历,分别提取出对应位置上的字符,将其转为整型后相乘。然后确定相乘后的两位数所在的位置 p1 和 p2,由于 p2 相较于 p1 是低位,所以将得到的两位数 mul 先加到 p2 位置上去,这样可能会导致 p2 位上的数字大于9,所以将十位上的数字要加到高位 p1 上去,只将余数留在 p2 位置,这样每个位上的数字都变成一位。然后要做的是从高位开始,将数字存入结果 res 中,记住 leading zeros 要跳过,最后处理下 corner case,即若结果 res 为空,则返回 "0",否则返回结果 res,代码如下:
class Solution { public: string multiply(string num1, string num2) { int m=num1.size(); int n=num2.size(); vector<int>dp(m+n,0); string res; for(int i=m-1;i>=0;--i){ for(int j=n-1;j>=0;--j){ int tmp=(num1[i]-'0')*(num2[j]-'0'); int p1=i+j,p2=i+j+1; int val=dp[p2]+tmp; dp[p1]+=val/10; dp[p2]=val%10; } } for(auto dd:dp){ if(!res.empty() || dd!=0){ res+=(dd+'0'); // 避免了前面是0的元素 } } return res.size()>0 ? res:"0"; } };