标签:大数相乘 大数相加
大数相乘,分别都是用字符串表示的两个大数,求相乘之后的结果表示。
首先我们应该考虑一下测试用例会有哪些,先准备测试用例对防御性编程会有比较大的帮助,能够考虑一些极端情况。有以下几种用例:
1)"0","0"
2)"0","879127346783" 其中一个是零
3)"as234","123343" 存在非法字符
4)"000000000000001234","2546" 存在零前缀,有冗余计算
大概就这么多吧。
要想实现大数乘法,必然先实现大数相加和一个大数和一个数字相乘。这样大数相乘就可以分割迭代计算。
下面是算法,自己写的,可能存在冗余。
<span style="font-size:14px;">class Solution { public: string subTwoString(string num1,string num2) //大数相加 { string result = ""; int i = num1.length()-1; int j = num2.length()-1; int plus = 0;//进位 while(i>=0 && j>=0) { int temp = num1[i]-'0' + num2[j]-'0' + plus;//不能忘掉进位 result =char(temp%10+'0')+ result; plus = temp/10; i--;j--; } if(i>=0)//一种一个没有加完,不全结果,当然还有进位 { while(i>=0) { int temp = num1[i]-'0' + plus; result =char(temp%10+'0')+ result; plus = temp/10; i--; } } if(j>=0) { while(j>=0) { int temp = num2[j]-'0' + plus; result =char(temp%10+'0')+ result; plus = temp/10; j--; } } if(plus != 0)//最后进位不为零是要在结果头部加上 result = char(plus+'0')+result; return result; } string multi(string num1,int num)//大数和一位数字相乘 { int len = num1.length()-1; int plus = 0; string result = ""; while(len>=0) { int temp = (num1[len] - '0') * num + plus;//plus刚开始是忘掉的,也不能写在括号内,跟加法不同 result = char(temp%10+'0') + result; plus = temp/10; len--; } if(plus != 0) result = char(plus+'0') + result; return result;} string multiply(string num1, string num2) {//大数相乘 if(num1.length() == 0 || num2.length() ==0) return 0; if(num1 == "0"|| num2 == "0") return "0"; string result = ""; int len1 = num1.length(); int len2 = num2.length(); for(int i = 0;i<len1;i++) if(!isdigit(num1[i]))//是否存在数字 return 0; for(int j = 0;j<len2;j++) if(!isdigit(num2[j])) return 0; for(int k = len2-1;k>=0;k--) { string temp = multi(num1,num2[k]-'0'); for(int l = len2-k-1;l>0;l--) temp = temp + "0"; result = subTwoString(result,temp); } return result; } };</span>
下面是另一种方法,不是按照手算乘法计算的,使用了辅助数组利用特点写的:
思路:如果两个大数分别为m和n位,那么结果最多为m+n位,或者为m+n-1位(最后不存在进位)。比如123和23相乘。
0 | 0 | 3 | 6 | 9 |
0 | 2 | 4 | 6 | 0 |
0 | 2 | 7 | 12 | 9 |
0 | 2 | 8 | 2 | 9 |
求进位,知道最开始。最后,再把他们转化成字符串即可。
<span style="font-size:14px;">string multiply(string num1, string num2) { if(num1=="0" || num2=="0") return "0"; int l1 = num1.length(), l2 = num2.length(); int* n1 = new int[l1]; int* n2 = new int[l2]; int* res = new int[l1+l2]; memset(res,0,sizeof(int)*(l1+l2)); for(int i=0; i<l1; ++i) n1[i] = num1[i] - '0'; for(int i=0; i<l2; ++i) n2[i] = num2[i] - '0'; for(int i=0; i<l1; ++i) for (int j=0; j<l2; ++j) res[i+j+1] += n1[i]*n2[j]; string ss = ""; for (int k=l1+l2-1; k>=0; --k){ if(k>0) res[k-1] += res[k]/10; res[k] %= 10; ss = char(res[k]+'0')+ss; } ss = ss[0]=='0'? ss.substr(1):ss; //return ss.empty()?"0":ss; return ss; }</span>
每日算法之三十四:Multiply Strings,布布扣,bubuko.com
标签:大数相乘 大数相加
原文地址:http://blog.csdn.net/yapian8/article/details/30997779