题目描述
给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。
题目保证至少有一个词不在禁用列表中,而且答案唯一。
禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/most-common-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
C++
//#include <iostream>
//#include <sstream>
//#include <vector>
//using namespace std;
class Solution {
public:
//哈希表排序,按照值排序
static bool cmp2(pair<string, int>a, pair<string, int> b) {
return a.second > b.second;//对于second的升序
}
//string 按照空格分割
vector<string> split(string s, char delim){
vector<string> v;
stringstream stringstream1(s); //stringstream主要用于字符串分割;
string tmp;
while(getline(stringstream1, tmp, delim)){ //学到了,遇到delim就停止读
transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower); //转小写
v.push_back(tmp);
// cout<<tmp<<" ";
}
return v;
}
string mostCommonWord(string paragraph, vector<string>& banned) {
/*
将标点符号已空格代替;
将段落按照空格拆分到数组;
将数组中的单词按照频率存储到哈希表;
以此取频率最高的单词,判断是否在禁用列表中,如果不在,就输出;我这里有个bug是总是有“”的频率
*/
//标点符号以空格代替
for (int j=0;j<paragraph.size();j++) {
if(ispunct(paragraph[j]))
{
paragraph=paragraph.replace(paragraph.find(paragraph[j]),1," "); //将标点符号替换位空格
}
}
//分割字符串
vector<string> a=split(paragraph,' ');
unordered_map<string,int> this_map; //存储所有单词的频率
for(int i=0;i<a.size();i++){
if(this_map.find(a[i])!=this_map.end()){
this_map[a[i]]++;
}
else{
this_map[a[i]]=1;
}
}
//哈希表转为vector 用于排序求最大值
vector<pair<string, int>> frequency_vec;
for (auto it = this_map.begin();it!= this_map.end();it++) {
frequency_vec.push_back(make_pair(it->first, it->second));
}
sort(frequency_vec.begin(), frequency_vec.end(), cmp2); //vector对按照第二个值排序
string answer;
//判断是否在禁用列表里
for (auto it = frequency_vec.begin(); it != frequency_vec.end(); it++){
if(it->first==""){
continue;
}
if(find(banned.begin(),banned.end(),it->first) ==banned.end()){ //这里的->不能用.
answer= it->first;
break;
}
}
return answer ;
}
};
参考
getline函数详解
stringstream学习
C++进行字符串分割
C++删除字符串中特定字符
字符串大小写转换
C++删除空格和标点符号
C++string中字符串替代
提交后执行速度挺快的,就是内存占用太高了。