前K个高频单词-c++实现

news2024/12/23 4:30:54

692. 前K个高频单词 - 力扣(LeetCode)

 

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

示例 1:

输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i" 在 "love" 之前。

 我们可以先把 words 当中的单词按照 pair<string,int>的方式放到 一个 map 当中去,然后使用 sort()函数对 map 当中的 int (词频)进行排序,再把 排好序的 string ,放到一个 string vector 当中返回。

但是 sort()函数支持的是 随机迭代器,而 map 是双向迭代器,所以 map 不能直接用于 sort()函数,所以,我们想到把 map 当中的数据(key-value)放到一个 vector<pair<string,int>>当中去,因为 vector 的迭代器是随机迭代器,所以能使用 sort()函数。

但是,如果我们想要 使用 pair对象当中的 int (词频)来排序的话,在 sort()当中是支持仿函数的设定的,在 sort()的第三个参数,就是仿函数,所以,我们需要自己实现一个 int 比较的仿函数:
 

    class Greater
    {
        bool operator()(const int& x, const int& y)
        {
            return x > y;
        }
    };

然后在调用 sort()函数的时候调用这个 Greater的匿名对象就行了:

// 因为map 的迭代器是双向迭代器,不能用sort(),sort()需要随机迭代器
        vector<pair<string, int>> sortv(StringMap.begin(), StringMap.end());
        sort(sortv.begin(), sortv.end(), greater());

注意,这里给仿函数的形式是给 greater(),匿名对象的形式,因为 sort()函数是以参数列表的形式接收 这个 仿函数(其实就是一个类),所以要接受一个对象。

而在模版参数当中接收的仿函数,接收的是类型,所以是以 greater<T> 这样的形式给的,如下所示:
 

 当上述工作都完成之后,我们发现,我们输出的结果有误:
 

 由上述结果可知,并不是完全无序的,而是 一组一组 的无序。通过观察发现,是sort()函数的问题,sort()函数的底层是使用快排来实现的,快排是不稳定的排序,所谓不稳定就是,同一个值,应该按照原本在数组当中存储的顺序来进行排序。这才是稳定的,但是 快排是不稳定的。

所以才出现了上述的输出错误。

其实在库当中,sort()函数有一个 优化函数 :stable_sort(),这个就是 稳定的 快排。

 完整代码:

class Solution {
public:
    // 用于比较 int(词频)的仿函数
    // 可以使用 class,但是 class 当中成员不加 权限修饰符默认是 private
    // struct 默认是 public 的
    struct Greater
    {
        bool operator()(const pair<string, int>& x, const pair<string, int>& y)
        {
            return x.second > y.second;
        }
    };

    // 主函数
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string, int> StringMap;
        for(auto e : words)
        {
            StringMap[e]++;
        }

        // 因为map 的迭代器是双向迭代器,不能用sort(),sort()需要随机迭代器
        vector<pair<string, int>> sortv(StringMap.begin(), StringMap.end());
        stable_sort(sortv.begin(), sortv.end(), Greater());

        vector<string> retvector;
        for(int i = 0;i < k;i++)
        {
            retvector.push_back(sortv[i].first);
        }

        return retvector;
    }
};

当然,使用 sort()函数也可以解决,sort()函数不稳定,我们在 仿函数比较规则当中控制就可以了(控制,当词频相同时候,string排序当中小的在前):

class Solution {
public:
    // 用于比较 int(词频)的仿函数
    // 可以使用 class,但是 class 当中成员不加 权限修饰符默认是 private
    // struct 默认是 public 的
    struct Greater
    {
        bool operator()(const pair<string, int>& x, const pair<string, int>& y)
        {
            // 控制,当词频相同时候,string排序当中小的在前
            return x.second > y.second || (x.second == y.second && x.first < y.first);
        }
    };

    // 主函数
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string, int> StringMap;
        for(auto e : words)
        {
            StringMap[e]++;
        }

        // 因为map 的迭代器是双向迭代器,不能用sort(),sort()需要随机迭代器
        vector<pair<string, int>> sortv(StringMap.begin(), StringMap.end());
        sort(sortv.begin(), sortv.end(), Greater());

        vector<string> retvector;
        for(int i = 0;i < k;i++)
        {
            retvector.push_back(sortv[i].first);
        }

        return retvector;
    }
};

其实不使用 sort()之类的排序函数也是可以实现的,map 本身在输出的时候就有排序的效果,我们可以先用map 按string 来排序(string作为key),再用 int(词频)来排序就可以实现了(int 作为 key)。

但是注意,我们要的结果是降序的前 k 个,但是 map 默认是 升序的,如果 默认升序的后 k 个话,string 排序是反的。

其实,map 还有一个模版参数,可以控制升序和降序:

 他默认是 less()仿函数,我们传入一个库当中的 greater()仿函数就可以了:
完整代码实现:
 

class Solution {
public:
    // 主函数
    vector<string> topKFrequent(vector<string>& words, int k) {
        // 排序string
        map<string, int> StringMap;
        for(auto e : words)
        {
            StringMap[e]++;
        }

        // 排序 int(词频)
        multimap<int, string , greater<int>> intMap;
        for(auto& e : StringMap)
        {
            intMap.insert(make_pair(e.second, e.first));
        }

        vector<string> retvector;
        auto it = intMap.begin();
        while(k--)
        {
            retvector.push_back(it->second);
            it++;
        }

        return retvector;
    }
};

 还可以使用 set 来实现,也是写仿函数按照 出现 频率去比,当出现频率相同,手动判断,然后进行处理(再去按照字典排)。

代码实现:
 

class Solution {
public:
	class Compare
	{
	public:
		// 在set中进行排序时的比较规则
		bool operator()(const pair<string, int>& left, const
			pair<string, int>& right)
		{
			return left.second > right.second;
		}
	};
	vector<string> topKFrequent(vector<string>& words, int k)
	{
		// 用<单词,单词出现次数>构建键值对,然后将vector中的单词放进去,统计每
		//个单词出现的次数
		map<string, int> m;
		for (size_t i = 0; i < words.size(); ++i)
			++(m[words[i]]);
		// 将单词按照其出现次数进行排序,出现相同次数的单词集中在一块
		multiset<pair<string, int>, Compare> ms(m.begin(), m.end());
		// 将相同次数的单词放在set中,然后再放到vector中
		set<string> s;
		size_t count = 0; // 统计相同次数单词的个数
		size_t leftCount = k;
		vector<string> ret;
		for (auto& e : ms)
		{
			if (!s.empty())
			{
				// 相同次数的单词已经全部放到set中
				if (count != e.second)
				{
					if (s.size() < leftCount)
					{
						ret.insert(ret.end(), s.begin(), s.end());
						leftCount -= s.size();
						s.clear();
					}
					else
					{
						break;
					}
				}
			}
			count = e.second;
			s.insert(e.first);
		}
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1012073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于Linux服务器.sh文件启动问题

问题描述 在linux服务器上使用文本编辑&#xff08;并非vim操作&#xff09;对.sh脚本文件进行修改后无法启动&#xff0c;显示’\r’识别错误等。 错误如下&#xff1a; 错误原因 因为.sh文件在经过这种编辑后格式产生了错误&#xff0c;由unix转为了doc格式&#xff0c;需…

Ae 效果:CC Particle Systems II

模拟/CC Particle Systems II Simulation/CC Particle Systems II CC Particle Systems II&#xff08;CC 粒子系统 II&#xff09;可用于生成和模拟各种类型的粒子系统&#xff0c;包括火焰、雨、雪、爆炸、烟雾等等。 与 CC Particle World 效果相比有许多类似的属性。最大的…

华为云云耀云服务器L实例评测|部署功能强大的监控和可视化工具Grafana

应用场景 Grafana介绍 Grafana是一个功能强大的监控和可视化工具&#xff0c;适用于各种行业和应用场景&#xff0c;如IT运维监控、网络监控、能源管理、金融市场分析等。它提供了灵活的数据源支持、强大的可视化功能和告警机制&#xff0c;以及注释和过滤功能&#xff0c;使…

阿里云服务器全方位介绍_优势_使用场景_限制说明

阿里云服务器是什么&#xff1f;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;云服务器可以降低IT成本提升运维效率&#xff0c;免去企业或个人前期采购IT硬件的成本&#xff0c;阿里云服务器让用户像使用水、电、天然气等公共资源一样便捷、高效地使用服务器…

使用cpolar配合Plex打造个人媒体站,畅享私人影音娱乐空间

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频&#xff0c;已经算是生活中稀松平常的场景了&#xff0c;特别是各…

langchain+GPT+neo4j 图数据库

neo4j版本是5.11.0,langchain的版本 0.0.288下载apoc插件 https://neo4j.com/docs/apoc/current/installation/ neo4j.conf文件把apoc.*添加到dbms.security.procedures.unrestricted配置项 使用return apoc.version()来查看是否安装成功 pip install neo4j图 参考官网&…

以太网的简单概念、MAC地址与IP地址的关系

以太网 DIX Ethernet V2标准的局域网------以太网。 IEEE 802.3标准和DIX Ethernet V2标准很相似&#xff0c;只有些许区别&#xff0c;不严格的来说&#xff0c;802.3局域网也叫做以太网。以太网是一个局域网&#xff0c;信息以广播的形式发送。 IEEE 802标准定义的局域网参…

哈工大校园网显示IP地址错误连接不上

您当前获取到的IP地址有误&#xff0c;请重新开关无线获取IP地址(注:电脑端还可以通过cmd窗口&#xff0c;输入ipconfig /release、ipconfig /renew命令)。如未解决此问题请联系网络安全和信息化办公室处理。 当校园网登录时会出现如上情况&#xff0c;并且当你按照他的方法尝试…

vue2使用vuedraggable实现拖拽删除添加重置功能

需求&#xff1a;要输入xx阶段&#xff0c;之后输入后显示但是要可以自己手动排序和删除&#xff0c;以免写错了&#xff0c;并且做了判断&#xff0c;如果重复输入的话会提示&#xff0c;不会让他添加&#xff0c;点击重置功能后一键清空所有输入 1.效果 2.下载插件 我直接下…

【Linux】自动化构建工具:make/Makefile

​&#x1f47b;内容专栏&#xff1a; Linux操作系统基础 &#x1f428;本文概括&#xff1a; 工具使用的背景、理解make/makefile工具、探索工作原理(文件修改时间的对比)、.PHONY伪目标、特性等。 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1…

18.3 【Linux】登录文件的轮替(logrotate)

18.3.1 logrotate 的配置文件 logrotate 主要是针对登录文件来进行轮替的动作&#xff0c;他必须要记载“ 在什么状态下才将登录文件进行轮替”的设置。logrotate 这个程序的参数配置文件在&#xff1a; /etc/logrotate.conf /etc/logrotate.d/ logrotate.conf 才是主要的参…

无涯教程-JavaScript - ADDRESS函数

描述 给定指定的行号和列号,您可以使用ADDRESS函数获取工作表中单元格的地址。 如,ADDRESS(2,3)返回$C $2。再举一个Example,ADDRESS(77,300)返回$KN $77。您可以使用其他函数(如ROW和COLUMN函数)为ADDRESS函数提供行号和列号参数。 语法 ADDRESS (row_num, column_num, [a…

跨境电商和TikTok广告:突破地理界限的机会

随着全球数字化的快速发展&#xff0c;跨境电商已经成为了现代商业的关键驱动力。同时&#xff0c;TikTok作为一款全球范围内广受欢迎的社交媒体平台&#xff0c;也在商业领域崭露头角。 本文将探讨跨境电商如何与TikTok广告相结合&#xff0c;为企业提供突破地理界限的机会。…

苹果宣布9月26日发布全新macOS Sonoma系统 新增不少实用功能

苹果公司在召开的特别活动中&#xff0c;宣布将于 9 月 26 日正式发布 macOS Sonoma&#xff0c;用户可以打开“设置”->“通用”->“软件更新”路径进行更新&#xff0c;新版本主要增强空间函数、为 AirPods 测试自适应音频、个性化音量和对话感知等新功能。 macOS Sono…

1.0零基础尝试DCM通讯(c-store)

前言 本项目是对医院放疗及相关设备的互通互联。对dcm文件及数据协议是本项目的基础。 今天在项目组成员支持下,对dcm通讯进行了初步的尝试,有人之路,这个过程可以说是非常愉快,于是乎准备将这个愉快的过程记录,方便自己查阅和后来人。 c-store 本次的安装和测试使用的…

乔哈里视窗:助力项目团队高效沟通

项目研发通常涉及多个团队成员、不同的职能部门和利益相关者&#xff0c;如果干系人间缺乏沟通&#xff0c;缺乏对项目目标、需求的共识和理解&#xff0c;团队成员间容易产生隔阂和矛盾&#xff0c;无法有效协调和管理&#xff0c;导致项目无法按时交付、质量下降、成本增加等…

视频怎么压缩?把视频压缩的小一点这样做

视频压缩在我们的生活和工作中有着广泛的应用需求&#xff0c;是一种减少视频文件大小的方法&#xff0c;可以给我们带来以下几个方面的作用&#xff1a; 1、减少存储空间占用&#xff1a;视频压缩可以显著减少视频的大小&#xff0c;从而腾出更多的存储空间&#xff0c;对于手…

一套精简的springboot后台管理系统

概述 本后台管理系统&#xff0c;基于SpringBoot2.0 Spring Data Jpa Thymeleaf Shiro 开发的后台管理系统&#xff0c;采用分模块的方式便于开发和维护&#xff0c;拓展性高&#xff0c;可作为您后台开发的基础框架 详细 运行截图&#xff1a; 项目结构&#xff1a; 详细…

EndNote21 | 杂志输出样式(参考文献格式模板)下载及安装

EndNote | 杂志输出样式下载及安装 一、参考文献格式下载二、参考文献格式安装 在《 Endnote: 文献条目的添加编辑引用文献全称与缩写的互相转换》文章中&#xff0c;介绍了如何手动编辑杂志输出样式&#xff0c;本文主要介绍如何从官网快速下载并安装所需杂志输出样式。 一、…

程序单实例运行的一种实现

技术背景知识 来自《Windows核心编程》 创建自定义段 Section 来自《Windows核心编程》 举例&#xff08;获取当前总共运行的实例数&#xff09; 创建自定义段并设置属性 #include "stdafx.h" #include "MFCApplication1.h" #include "MFC…