1,题目要求
Given a paragraph and a list of banned words, return the most frequent word that is not in the list of banned words. It is guaranteed there is at least one word that isn’t banned, and that the answer is unique.
Words in the list of banned words are given in lowercase, and free of punctuation. Words in the paragraph are not case sensitive. The answer is in lowercase.
Note:
1 <= paragraph.length <= 1000.
1 <= banned.length <= 100.
1 <= banned[i].length <= 10.
The answer is unique, and written in lowercase (even if its occurrences in paragraph may have uppercase symbols, and even if it is a proper noun.)
paragraph only consists of letters, spaces, or the punctuation symbols !?’,;.
Different words in paragraph are always separated by a space.
There are no hyphens or hyphenated words.
Words only consist of letters, never apostrophes or other punctuation symbols.
即,给出一个字符串,以及一个禁用单词序列。求出出现次数最多且不在禁用单词系列里的单词。
2,题目思路
根据题目,输入为字符串和向量,分别为给定的句子和禁用单词序列(不止一个)。
因此,首先需要对输入的字符串进行处理:将非字母的部分转化为空格,以及将大写字母全部改写为小写部分。
然后对于这样的字符串,利用istringstream方法将空格分割的字符串转化为一个个单独的字符串构成的单词。
最后,对这些单词,依次进行遍历并:判断其是否在禁用数组中,并判断其出现次数是否是最大的。如果满足条件,则记下该单词。遍历结束后,返回找到的单词即可。
3,程序源码
class Solution {
public:
string mostCommonWord(string paragraph, vector<string>& banned) {
unordered_map<string, int> wordCount;
unordered_set<string> bannedWord(banned.begin(),banned.end());
for(auto &c:paragraph)
{
if(isalpha(c))
c = tolower(c);
else
c = ' ';
}
istringstream s_para(paragraph); //头文件为sstream
pair<string, int> res ("", 0);
string tmp;
while(s_para >> tmp)
{
if(bannedWord.find(tmp) == bannedWord.end() && ++wordCount[tmp] > res.second ) //set没有查找到的结果,最后找到了end并返回
res = make_pair(tmp, wordCount[tmp]);
}
return res.first;
}
};
- 代码中,定义了一个unordered_map来记录对应单词及其出现的次数。定义了一个unordered_set来记录禁用的单词,这样做的目的是方便对其中的元素进行查找: find(A)方法。
//利用vector中的迭代器对unordered_set进行构造
//方便快捷
unordered_set<string> bannedWord(banned.begin(),banned.end());
for(auto &c:paragraph)
对字符串的一种快速的遍历方法,其中c为引用的auto类型(也就是char类型,不过利用的auto的适用性更强),便于直接对字符串paragraph进行直接的操作。
isalpha(c) //判断字符是否为字母,返回值为bool类型
tolower(c) //将字母字符转换为小写形式,返回值为char类型
istringstream
的用法
首先,头文件为#include <sstream>
其次,istringstream是C++里面的一种输入输出控制类,它可以创建一个对象,然后这个对象就可以绑定一行字符串,然后以空格为分隔符把该行分隔开来。
//用法测试
#include<iostream>
#include<sstream>
using namespace std;
int main()
{
string str="Bob like eat apple";
istringstream s_test(str);
string s;
while(s_test>>s)
{
cout<<s<<endl;
}
return 0;
}
输出为:
Bob
like
eat
apple
pair
的用法
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如STL中的map就是将key和value放在一起来保存。
另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。例如题目中的这种应用——出现次数的最大值以及最大值对应的单词(字符串)。
pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
利用make_pair函数进行构造:
对于pair类,由于它只有两个元素,分别名为first和second,因此直接使用普通的点操作符即可访问其成员。这点和map中的用法一样。
pair<int, double> p1;
p1 = make_pair(1, 1.2);
- set中的find方法
find方法在set中尽心查找是,会挨个进行查找,如果查到就返回该值,如果没有查到结尾还没有查到,就直接返回end。