前k个高频单词(C++实现)

简介: 前k个高频单词(C++实现)


题目


思路

通过统计字符串的出现次数,并根据出现次数和字典序对字符串进行排序,找出出现频率最高的前k个字符串。使用一个自定义的仿函数作为排序的比较函数,通过map容器进行统计,然后将结果存储在向量中返回


代码

//仿函数
    struct kvCom
    {
        bool operator()(const pair<string,int>& p1,const pair<string,int>& p2)
        {
            return p1.second>p2.second || (p1.second==p2.second && p1.first<p2.first);
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int> CountMap ;
        for (auto &e : words)
        {
            CountMap[e]++;
        }
        //sort中的支持的是随机迭代器,而map是双向迭代器,所有将map中的数据存到vector中再用sort
        vector<pair<string,int>> sortV(CountMap.begin(),CountMap.end());
        //稳定的sort
        //stable_sort(sortV.begin(),sortV.end(),kvCom());
        sort(sortV.begin(),sortV.end(),kvCom());//对次数排序
        vector<string> ret;
        for (int i=0;i<k;i++)
        {
            ret.push_back(sortV[i].first);
        }
        return ret;
    }

代码讲解

struct kvCom
    {
        bool operator()(const pair<string,int>& p1,const pair<string,int>& p2)
        {
            return p1.second>p2.second || (p1.second==p2.second && p1.first<p2.first);
        }
    };
  • struct kvCom:定义了一个结构体kvCom,它是一个仿函数(function object)。仿函数是重载了函数调用操作符operator()的对象,可以像函数一样被调用。在这个结构体中,重载了operator(),用于定义对存储字符串-整数对的pair进行比较的规则。
  • bool operator()(const pair<string,int>& p1,const pair<string,int>& p2):这是kvCom结构体中的函数调用操作符的重载。它接受两个参数,都是pair<string,int>类型的引用。函数的目的是比较这两个pair对象的大小,返回一个布尔值表示两个对象的大小关系。具体的比较规则如下:
    首先比较第二个元素(即整数部分)的大小,如果p1的第二个元素大于p2的第二个元素,则返回true,否则返回false。
    如果两个元素的第二个元素相等,那么比较第一个元素(即字符串部分)的大小,如果p1的第一个元素小于p2的第一个元素,则返回true,否则返回false。
vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int> CountMap ;
        for (auto &e : words)
        {
            CountMap[e]++;
        }
        //sort中的支持的是随机迭代器,而map是双向迭代器,所有将map中的数据存到vector中再用sort
        vector<pair<string,int>> sortV(CountMap.begin(),CountMap.end());
        //稳定的sort
        //stable_sort(sortV.begin(),sortV.end(),kvCom());
        sort(sortV.begin(),sortV.end(),kvCom());//对次数排序
        vector<string> ret;
        for (int i=0;i<k;i++)
        {
            ret.push_back(sortV[i].first);
        }
        return ret;
    }
  • map<string,int> CountMap:定义了一个map容器CountMap,用于统计每个字符串在words中出现的次数。map是一个关联容器,它存储了键-值对,其中键是唯一的,即每个字符串只会在map中出现一次,值表示字符串出现的次数。
  • for (auto &e : words):遍历words中的每个字符串,使用引用&e来获取字符串的引用。这样可以避免在循环中对字符串进行拷贝,提高性能。
  • CountMap[e]++:将当前遍历到的字符串e作为键,在CountMap中查找对应的值,并将其加1。如果e在CountMap中不存在,则会自动插入一个键为e,值为0的键-值对,然后将值加1。
  • vector<pair<string,int>> sortV(CountMap.begin(),CountMap.end()):sort中的支持的是随机迭代器,而map是双向迭代器,所有将map中的数据存到vector中再用sort。使用CountMap中的数据初始化一个存储字符串-整数对的sortV。这样做是为了将CountMap中的数据按照出现次数进行排序。
  • sort(sortV.begin(),sortV.end(),kvCom()):对sortV中的元素按照指定的排序规则进行排序。这里使用了kvCom结构体的对象作为比较函数,用来定义排序规则。排序的规则是按照字符串出现次数的降序排列,如果出现次数相同,则按照字符串的字典序(升序)进行排列。
  • vector ret:定义一个字符串向量ret,用于存储结果。
  • for (int i=0;i<k;i++):从排序后的向量sortV中取出前k个字符串。
  • ret.push_back(sortV[i].first):将第i个字符串的第一个元素(即字符串本身)添加到结果向量ret中。
  • return ret:返回存储了出现频率最高的前k个字符串的向量ret。

(本题完)

相关文章
剑指offer(C++)-JZ73:翻转单词序列(数据结构-队列 & 栈)
剑指offer(C++)-JZ73:翻转单词序列(数据结构-队列 & 栈)
|
6月前
|
C++ 索引
c++:string相关的oj题(415. 字符串相加、125. 验证回文串、541. 反转字符串 II、557. 反转字符串中的单词 III)
c++:string相关的oj题(415. 字符串相加、125. 验证回文串、541. 反转字符串 II、557. 反转字符串中的单词 III)
67 0
|
6月前
|
存储 C语言 容器
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别(下)
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别
46 1
|
6月前
|
存储 C语言 容器
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别(中)
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别
48 1
|
6月前
|
存储 自然语言处理 C语言
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别(上)
从C语言到C++_26(set+map+multiset+multimap)力扣692+349+牛客_单词识别
61 1
|
5月前
|
C++ 安全
高效遍历:C++中分隔字符串单词的3种方法详解与实例
拷贝并交换(Copy-and-Swap)是C++中实现赋值操作符和异常安全拷贝构造函数的技巧。它涉及创建临时对象,使用拷贝构造函数,然后交换数据以确保安全。C++11之前的策略在此后及C++11引入的移动语义和右值引用下仍有效,但后者提供了更高效的实现方式。
|
6月前
|
Linux 监控 Shell
Linux 终端命令之文件浏览(4) head, tail
Linux 终端命令之文件浏览(4) head, tail
61 0
Linux 终端命令之文件浏览(4) head, tail
|
6月前
|
Python C++ 机器人
C/C++每日一练(20230419) 插入区间、单词拆分、不同路径
C/C++每日一练(20230419) 插入区间、单词拆分、不同路径
46 0
C/C++每日一练(20230419) 插入区间、单词拆分、不同路径
|
6月前
|
Go C++ Java
C/C++每日一练(20230411) 排列序列、翻转字符串里的单词、能被13又能被20整除的四位正整数的和
C/C++每日一练(20230411) 排列序列、翻转字符串里的单词、能被13又能被20整除的四位正整数的和
60 0
C/C++每日一练(20230411) 排列序列、翻转字符串里的单词、能被13又能被20整除的四位正整数的和
|
6月前
|
Python C++ Java
C/C++每日一练(20230331) 单词长度、水果计费、条件分支结构
C/C++每日一练(20230331) 单词长度、水果计费、条件分支结构
75 0
C/C++每日一练(20230331) 单词长度、水果计费、条件分支结构