【C++】仿函数(less)

news2024/10/6 20:33:50

C++中的仿函数

class Solution {
public:

    struct cmp
    {
        bool operator()(const pair<string,int>&kv1,const pair<string,int>&kv2)
        {
            if(kv1.second<kv2.second) return true;

            if(kv1.second==kv2.second&&kv1.first>kv2.first) return true;

            return false;
        }
    };

    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int>mp;
        for(auto& w:words)
        {
            mp[w]++;
        }
        priority_queue<pair<string,int>,vector<pair<string,int>>,cmp>pq(mp.begin(),mp.end());
       
        vector<string>res;

        while(k--)
        {
            res.push_back(pq.top().first);
            pq.pop();
        }
        return res;
    }
};

对于以上代码一开始存在一点疑问,为什么自定义一下堆的排序规则还需要定义一个类、结构体然后再在类里面重写operator(),于是我跑去看了一下文档对priority_queue的定义。

嚯,比较器是一个类

这里的value_type是一个模板参数。

可以看到less<>当中没有具体的参数,typename显示的告诉编译器后面是一个类型,这里是告诉编译器,在Container这个类(容器)当中的value_type是一个类型。

less 是一个函数对象(即仿函数)或者函数模板,它不需要具体的变量名来执行比较操作。

<>用于指定类型,好让less的模板参数识别类型。

template <class T>
  struct less : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {
      return x<y;//升序,小的在前
  }
};

再来看之前模拟实现的priority_queue代码,真的是边学边忘。

template<class T, class Container = vector<T>,class Compare=std::less<T>>
    class priority_queue
    {
    public:
        priority_queue()
        {}

        template<class InputIterator>
        priority_queue(InputIterator first, InputIterator last)
        {
            while (first != last)
            {
                _con.push_back(*first);
                first++;
            }

            for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
            {
                Adjust_down(i);
            }
        }

        size_t size()
        {
            return _con.size();
        }

        void Adjust_up(size_t child)
        {
            Compare compare;
            size_t parent = (child - 1) / 2;
            while (child>0)
            {
                if (compare(_con[parent],_con[child]))
                {
                    std::swap(_con[parent], _con[child]);
                    child = parent;
                    parent = (child - 1) / 2;
                }
                else
                {
                    break;
                }
            }

        }

        void Adjust_down(size_t parent)
        {
            Compare com;
            size_t child = parent * 2 + 1;
            while (child < _con.size())
            {
                // 选出左右孩子中大的那一个
                //if (child+1 < _con.size() && _con[child+1] > _con[child])
                //if (child + 1 < _con.size() && _con[child] < _con[child + 1])
                if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
                {
                    ++child;
                }

                //if (_con[child] > _con[parent])
                //if (_con[parent] < _con[child])
                if (com(_con[parent], _con[child]))
                {
                    std::swap(_con[child], _con[parent]);
                    parent = child;
                    child = parent * 2 + 1;
                }
                else
                {
                    break;
                }
            }
        }

        void push(const T& val)
        {
            _con.push_back(val);
            Adjust_up(_con.size()-1);//调堆
        }

        void pop()
        {
            std::swap(_con[0], _con[_con.size() - 1]);
            _con.pop_back();
            Adjust_down(0);
        }

        const T& top()const
        {
            return _con[0];
        }

        bool empty()
        {
            return (_con.size() == 0);
        }

        bool empty() const 
        {
            return (_con.size()==0);
        }

    private:
        Container _con;//容器
    };

将重点抠出来

template<class T, class Container = vector<T>,class Compare=std::less<T>>
void Adjust_down(size_t parent)
        {
            Compare com;//比较器
            size_t child = parent * 2 + 1;
            while (child < _con.size())
            {
                if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
                {
                    ++child;
                }
                
                if (com(_con[parent], _con[child]))
                {
                    std::swap(_con[child], _con[parent]);
                    parent = child;
                    child = parent * 2 + 1;
                }
                else
                {
                    break;
                }
            }
        }
Compare com;//比较器
com(_con[child], _con[child + 1]);//直接调用重载的运算符operator()

就是这样通过重载operator()来改变排序规则的。

总结:less是一个类、通过调用operator()来实现排序规则

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

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

相关文章

JavaWeb01-Servlet-thymeleaf-mvd-dispatcher-controller

Servlet: servlet的基本作用 第一个servlet程序&#xff1a; //演示servlet的生命周期 public class Demo02Servlet extends HttpServlet {Overridepublic void init() throws ServletException {System.out.println("正在初始化。。。");}Overrideprotected void …

实例019 以图形按钮显示的界面

实例说明 菜单和工具栏虽然能方便用户操作程序的相应功能&#xff0c;但各有缺点。如果采用按钮式功能菜单&#xff0c;不但美观大方&#xff0c;而且操作灵活。当单击按钮时&#xff0c;用户区将显示相应的操作按钮组。下面介绍图形界面式菜单的设计方法。运行本例&#xff0…

【个人笔记】linux命令之cd

cd命令 cd&#xff08;英文全拼&#xff1a;change directory&#xff09;命令用于改变当前工作目录的命令&#xff0c;切换到指定的路径。 若目录名称省略&#xff0c;则变换至使用者的 home 目录 (也就是刚 login 时所在的目录)。 另外&#xff0c;~ 也表示为 home 目录 的…

恢复配置并减少网络停机时间

随着众多公司努力在商业世界中崭露头角&#xff0c;拥有可靠的 IT 基础架构比以往任何时候都更加重要。组织需要维护一个稳定的网络环境&#xff0c;避免不合时宜的网络中断以及网络连接中断、声誉受损、应用程序不可用和数据丢失。 Network Configuration Manager 提供了一种…

Debian 12上如何关闭nobody共享文件夹,一个能让INSCODE AI 创作助手不知所措的小问题

这个问题之前在Debian 10和11上都没有遇到过&#xff0c;换上Debian 12后Samba的设置就出现了状况&#xff0c;装上Samba后什么都没有设置就在局域网可以看到&#xff1a; 根据之前的经验在/etc/samba/smb.conf里查了很久也没有看出所以然来&#xff0c;后来又问了INSCODE AI…

ubuntu打开usb摄像头

文章目录 前言一、识别 usb 摄像头二、安装应用程序显示摄像头捕捉到的视频1、使用应用程序茄子&#xff08;cheese&#xff09;2、运行 cheese 捕捉视频 总结 前言 记录一下解决在 Linux 下打开 usb 摄像头界面黑屏的问题。 一、识别 usb 摄像头 1、保持在 ubuntu 界面&…

软件测试用例的八大步骤你都知道吗?

目录 第一步、UI体验测试 第二步、功能完整性测试 第三步、业务流程测试 第四步、容错机制测试 第五步、常规性测试 第六步、性能测试 第七步、交互体验测试 第八步、兼容性测试 总结&#xff1a; 第一步、UI体验测试 1.风格、样式、颜色是否协调 2. 界面布局是否整齐、…

【网站搭建】3 更换博客主题—butterfly

可以到官网选择想要更换的主题Themes | Hexo 我选用的是butterflyzhangzeli/hexo-theme-butterfly: A Hexo Theme: Butterfly (github.com) 在Hexo根目录打开终端执行拉去操作 下载配套文件 npm install hexo-renderer-pug hexo-renderer-stylus 打开_config.yml文件&#xf…

二维费用背包(既有最大体积限制,又多加了一个最大重量限制)

1:分析状态转移方程式 2:ACcode: #include<bits/stdc.h> using namespace std; const int N1e310; int f[N][N],v[N],w[N],m[N]; void solve() {int a,b,c;cin>>a>>b>>c;for(int i1; i<a; i) cin>>v[i]>>m[i]>>w[i];//酷似01背…

数仓虚拟化技术:PieCloudDB 通过中国信通院 2023 「可信数据库」性能评测的强力支撑...

“可信数据库”是国内首个数据库的评测体系&#xff0c;被业界广泛认可为产品能力重要的衡量标准之一。PieCloudDB 在该评测中展现出卓越的数据处理速度、稳定性和可扩展性&#xff0c;为用户提供了强大的数据分析和查询能力。 6 月 15 ~ 16 日&#xff0c;中国信通院 2023 上…

vue3笔记-脚手架篇

第一章 基础篇 第二章 脚手架篇 vue2与vue3的一些区别 响应式系统&#xff1a; Vue 2 使用 Object.defineProperty 进行响应式数据的劫持和监听&#xff0c;它对数据监听是一项项的进行监听&#xff0c;因此&#xff0c;当新增属性发生变化时&#xff0c;它无法监测到&…

0719_rasa网站的一些介绍

it’s not a bot, it’s your brand rasa is the leading open generative conversational ai platform for creating and managing ai assistants at scale. learn more talk with sales top enterprises trust rasa american express adobe dell accenture report ho…

使用Canal同步mysql数据到es

一、简介 Canal主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费。 当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x 二、工作原理 MySQL主备复制原理 MySQL master 将数据变更写入二进制日志( binary log, 其中记…

一篇文章带你用Jenkins和Kubernetes搭建DevOps平台

JenkinsKubernetes实现DevOps DevOps 介绍Jenkins环境准备准备JDK下载jdk安装jdk配置jdk环境变量 准备maven下载maven解压maven配置maven配置maven环境变量 安装Docker安装git 安装Jenkins初始化jenkins准备代码仓库和docker镜像仓库准备Kubernetes准备java项目搭建DevOps创建代…

ENSP实验一:防火墙基础配置

1、搭建拓扑图 配置client&#xff08;内网&#xff09;、FTP Server&#xff08;外网&#xff09;的IP地址 客户端设置&#xff1a; 服务端设置&#xff1a; 2、配置防火墙命名 进入防火墙&#xff0c;输入密码&#xff1a;默认为admin123 <USG6000V1>system-view /…

埃科光电在科创板上市:同创伟业、毅达资本为股东,实控人为董宁

7月19日&#xff0c;合肥埃科光电科技股份有限公司&#xff08;下称“埃科光电”&#xff0c;SH:688610&#xff09;在上海证券交易所科创板上市。本次上市&#xff0c;埃科光电的发行价为73.33元/股&#xff0c;发行数量为1700万股&#xff0c;募资总额约为12.47亿元&#xff…

Flutter 单线程模型保证UI运行流畅

Flutter 框架出色的渲染和交互能力。支撑起这些复杂的能力背后&#xff0c;实际上是基于单线程模型的 Dart。那么&#xff0c;与原生 Android 和 iOS 的多线程机制相比&#xff0c;单线程的 Dart 如何从语言设计层面和代码运行机制上保证 Flutter UI 的流畅性呢&#xff1f; 因…

❤️创意网页:HTML5 Canvas技术实现绚丽多彩的烟花特效教程

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

HhybridApp开发模式,你了解多少?

Hhybrid App顾名思义就是原生 App 与 Web App 的结合。它的壳是原生 App&#xff0c;但是里面放的是网页。 可以理解成&#xff0c;混合 App 里面隐藏了一个浏览器&#xff0c;用户看到的实际上是这个隐藏浏览器渲染出来的网页。 随着 Web 技术和移动设备的快速发展&#xff0…

长沙打造“全球研发中心城市”,智能网联产业如何交卷?

作者 | 魏启扬 来源 | 洞见新研社 知乎上有一个浏览超百万的热门问题——“大家怎么看待长沙这个城市&#xff1f;” 答主“星球研究所”的回答获得了高赞&#xff0c;“这是一个天性如火的城市”。 网红城市的外衣下&#xff0c;从湖南卫视的综艺节目&#xff0c;到网红美…