Leetcode-43.Multiply Strings
来源:互联网 发布:三毛的梦里花落知多少 编辑:程序博客网 时间:2024/05/27 02:32
本次做的是大数相乘的题目。
1. 题目
Given two non-negative integers num1
and num2
represented as strings, return the product of num1
and num2
.
Note:
- The length of both
num1
andnum2
is < 110. - Both
num1
andnum2
contains only digits0-9
. - Both
num1
andnum2
does not contain any leading zero. - You must not use any built-in BigInteger library or convert the inputs to integer directly.
给出两个非负的数字num1和num2,用字符串string来表示,返回num1和num2相乘的结果。
注意:
- num1和num2的长度小于110;
- num1和num2都是只包含0-9的数字;
- num1和num2度的高位不是0;
- 不能使用已有的BigInteger 库或者直接将输入转化为整数。
2.思路
题目很容易理解,就是字符串的相乘,最简单的思路,就是按照手算时的竖式乘法来计算:较长的数字num1在上,较短的数字 num2在下,举个例子。num1乘以num2的每一位,得到的结果存储起来,再进行相加。按照这种思路,存储结果可以用字符串也可以用数组。我是采用数组的形式。数组r初始化为"num2.length x(num1.length()+num2.length())"的大小,且全为0.因为num2的长度决定了num1要乘几次,如下面例子,num1要乘4次,得到四行结果。最后相加的时候,结果的位数最多是num1.length() + num2.length()这么长。因此,得到这个全0矩阵后,每一列相加,就相当于竖式的加法计算。
1 2 3 4 5
x 2 2 2 4
————————————
000049380000246900002469000024690000
————————————
0 2 7 4 5 5 2 8 0
按照上面例子的算法,可以得到计算结果。在最高位时,判断如果是0,则舍弃该位,若是有进位,则需要保存。
注意的是,当num1或者num2其中一个是0时,不需要计算,直接返回字符串“0”;还有,num1始终是较长的字符串,num2是较短的字符串。
3.代码
string multiply(string num1, string num2) { //如果两个字符串有一个为0,那么相乘结果直接为0 if (num1 == "0" || num2 == "0") return "0"; //比较两个字符串的长度,长的作为num1 if (num1.length() < num2.length()) { string s; s = num1; num1 = num2; num2 = s; } int i,j; int k=0; int len = num1.length() + num2.length(); //定义一个初始化为全0的矩阵来存放num1乘以num2每一位的计算结果,矩阵行数是num2的长度,矩阵列数是num1长度+num2长度 int r[num2.length()][len]; for(i = 0; i < num2.length(); i ++) for(j = 0; j < len; j ++) r[i][j] = 0; //c用于记录进位 int c = 0; //num2的最后一位开始,num1也是从最后一位开始,依次按位相乘 for(i = num2.length()-1; i >= 0; i --){ for(j = num1.length() - 1; j >=0 ; j --){ int temp = (num1[j]-'0') * (num2[i]-'0') + c; c = temp / 10; //num1乘以num2的第i位存放在第k行,k从0开始 r[k][i+j+1] = temp % 10;; } r[k][i+j+1] = c; k ++; c = 0; } //sum用于记录矩阵每一列数字加起来的结果,c记录进位 int sum = 0; c = 0; string res = ""; for(int col = len-1; col >= 0; col --){ for(int row = 0; row < num2.length(); row ++){ sum += r[row][col]; } sum += c; c= sum / 10; //如果最高位这一列结果是0,则不需要加到res中 if((col == 0) && (sum == 0)) break; res += (sum%10)+'0'; sum = 0; } //翻转字符串 reverse(res.begin(), res.end()); return res; }
4.优化的方法
字符串很长的时候,必然会有很多重复的数字,那么此时可以进行优化。定义一个int数组,记为h,大小为10,分别表示num2中数字0-9出现过没有,出现过,则将出现在第几位记录在数组h中。以上面例子来讲,当num1乘以num2中的4时,记录h[4] = k, 表示在矩阵的第k行;当num1乘以num2中的第一个2时,记录h[2] ;那么当再次出num2中再出现2时,就可以直接从矩阵的r[h[2]]行取结果,放在当前行,并前移几个单位即可。
我认为这种做法在字符串长时会有一定的改进。代码添加修改部分如下:
int h[10]; for(i = 0; i < 10; i ++) h[i] = 0; //c用于记录进位 int c = 0; //num2的最后一位开始,num1也是从最后一位开始,依次按位相乘 for(i = num2.length()-1; i >= 0; i --){ if (h[(num2[i]-'0')] != 0) { int d = k - h[(num2[i]-'0')]; for(int l = len - 1; l >= d;l--) r[k][l-d] = r[h[(num2[i]-'0')]][l]; } else{ for(j = num1.length() - 1; j >=0 ; j --){ int temp = (num1[j]-'0') * (num2[i]-'0') + c; c = temp / 10; //num1乘以num2的第i位存放在第k行,k从0开始 r[k][i+j+1] = temp % 10;; } h[(num2[i]-'0')] = k; r[k][i+j+1] = c; } k ++; c = 0; }
0 0
- [LeetCode]43.Multiply Strings
- LeetCode --- 43. Multiply Strings
- [Leetcode] 43. Multiply Strings
- [leetcode] 43.Multiply Strings
- 43. Multiply Strings LeetCode
- leetcode 43. Multiply Strings
- LeetCode 43. Multiply Strings
- LeetCode 43. Multiply Strings
- LeetCode 43. Multiply Strings
- [leetcode] 43. Multiply Strings
- Leetcode 43. Multiply Strings
- (Leetcode)43. Multiply Strings
- LeetCode - 43. Multiply Strings
- leetcode 43. Multiply Strings
- [LeetCode] 43. Multiply Strings
- leetcode 43. Multiply Strings
- Leetcode 43. Multiply Strings
- leetcode 43. Multiply Strings
- Final Cut Pro X 学习笔记
- 将日志保存到文件中
- Dojo1.11官方教程文档翻译(6.1)Dojo Object Store
- 自定义通讯协议
- 虚拟ip +keeplalived+nginx 负载实现
- Leetcode-43.Multiply Strings
- 记一次hashmap乱序的问题
- 从百度统计看到的一些有意思的事情
- java中有三种移位运算符
- Embedding Deep Metric for Person Re-identification: A Study Against Large Variations
- HDU2041 超级楼梯
- node中的readline模块
- hadoop入门程序wordcount 解析
- Java大牛养成记——图片上传