编程提高班1:Jewels and Stones问题
You're given strings J representing the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels.
The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so "a" is considered a different type of stone from "A".
Example 1:
Input: J = "aA", S = "aAAbbbb"
Output: 3
Example 2:
Example 2:
Input: J = "z", S = "ZZ"
Output: 0
Note:
- S and J will consist of letters and have length at most 50.
- The characters in J are distinct.
通用解法
相信很多人的解法是下面这样:
class Solution {
public:
int numJewelsInStones(string J, string S) {
int I=0;
int cout=0;
for(;i<J.length();i++){
int j=0;
for(;j<S.length();j++){
if(J[i]==S[j]){
cout++;
}
}
}
return cout;
}
};
这样的代码不是很推荐,首先晦涩难懂,其次速度并不会得到提升,而下面的解法会让您眼前一亮。
高级解法
class Solution {
public:
int numJewelsInStones(string J, string S) {
unordered_set<char> jewels(std::begin(J), std::end(J));
int res = 0;
std::for_each(std::begin(S), std::end(S), [&res, &jewels](char ch) { res += jewels.count(ch); });
return res;
}
};
利用STL和for_each的配合,大大缩短了代码的长度
unordered_set的解释:
这里的STL用的是哈希容器:把J放入jewels容器中。
其中的count方法可以判断元素是否在STL中
for_each的解释:
for_each可以翻译成下面这样:
while (first!=last) {
fn (*first);
++first;
上面提到的fn,是用的Lambda表达式,没有函数名,函数体是res +=jewels.count(ch)。
中括号的解释[]
这是c++11以后可以用的Lambda表达式。
方括号的作用是捕获外部的变量。
'&'是按引用捕获,也就是说在这个没有名字的函数中可以用方括号中列出来的变量,按引用捕获你参考按引用传递参数。
总结
此题目是简单的字符串匹配问题,我们只是用到了for操作,巧妙利用了c++的容器,特点是代码量很精简。
如果想要提高速度,不妨考虑KMP算法