题目
思路
题目给出两个字符串表示一个整数,要求这两个字符串代表的数字的乘积,并且他们的乘积也为字符串的形式,题目还限制了不能将这两个字符串直接转换为整数来处理。那么我们的思路是怎么样的呢,下面我们来看下面这个式子:
整数123可以表示为: 123=1*10^2+2*10^1+3*10^0
整数456可以表示为: 456=4*10^2+5*10^1+6*10^0
那么:
123*456=(1*10^2+2*10^1+3*10^0)*(4*10^2+5*10^1+6*10^0)
=3*10^0*6*10^0+3*10^0*5*10^1+3*10^0*4*10^2+2*10^1*6*10^0+2*10^1*5*10^1+2*10^1*4*10^2……(采用分配律)
那么将式子展开之后,我们就把幂次相同的相加,然后如果幂次的数字大于等于10,则选择进位,所以该题的思路大致如此:
- 选择其中一个字符串中的数字,分别与另外一个字符串的各个数字相乘,字符串中的数字带上幂次,那么一个数字的幂次就等于字符串长度-该位置-1
- 设置一个map,该map元素中的关键字就为一个相乘子项的幂次,那么每次相乘我们就将具有相同幂次的项相加,若相加后的结果大于等于10,那么向前进位
相关代码如下:
class Solution {
public:
string multiply(string num1, string num2) {
int m = num1.size();
int n = num2.size();
map<int, int> Map;
string res;
if (!m || !n)return res;
//如果某个字符串为0,则直接返回结果"0"
if (num1 == "0" || num2 == "0") {
res = "0";
return res;
}
for (int i = m - 1; i >= 0; i--) {
int ch1 = num1[i] - '0';
for (int j = n - 1; j >= 0; j--) {
int ch2 = num2[j] - '0';
int s = m + n - i - j - 2;//该相乘项的幂次
int ch3 = ch1 * ch2 + Map[s];//相同幂次相加的结果
//如果具有相同幂次的项相加>=10,则进行进位操作
if (ch3 >= 10) {
Map[s] = (ch3 % 10);
Map[s + 1] = (Map[s + 1] + ch3 / 10);
}
else Map[s] = ch3;
}
}
//将输出结果转化为字符串输出
auto s = Map.end();
while (Map.begin() != s) {
/*char t = (Map.end()-1)->second + '0';*/
--s;
char t = s->second + '0';
res.push_back(t);
}
return res;
}
};
总结
在使用map的过程中遇到了几个易错点:
(1)首先就是关于map迭代器进行算术运算的问题:
map.end()-1;
考虑上面的语句,系统会报错,查了一下:能进行算术运算的迭代器只有随即访问迭代器,要求容器元素存储在连续内存空间里,vector,string,deque的迭代器是有加减法的,但是map,set,multimap,multiset的迭代器是没有加减法的,list也不可以
(2)相比较顺序容器,关联容器的begin和end不能使用自增或者自减进行访问操作
对于上图中的语句,我们发现陷入了死循环,换成begin()迭代器也不行,似乎begin和end迭代器都是const类型的,若想使用迭代器访问map中的元素,则可这样子:
(3)通过使用迭代器来访问map对象中的first和second数据成员时,有两种访问形式,一个就是先通过操作符"*“解引用迭代器,然后再通过成员访问操作符’.'进行访问,另外一个就是结合解引用和成员操作,使用箭头运算符”->"来访问map元素中的成员
(4)指针是狭义上的迭代器,迭代器是指针的泛化和抽象