C++ 多条件比较的几种实现方式

news2025/4/16 23:29:40

1 sort()使用自定义比较器

sort使用方法
头文件 #include
sort函数有三个参数:
sort(first,last,cmp);
其中,first是元素的起始地址,last是结束地址,cmp是排序的方式。对[first,last)(一定要注意这里的区间是左闭又开)区间内数据根据cmp的方式进行排序。也可以不写第三个参数,此时按默认排序,从小到大进行排序。

sort() 中的比较函数 compare 要声明为静态成员函数或全局函数,不能作为普通成员函数,否则会报错。

cmpChar实现功能:大写字母大于小写字母,小写字母按 a-z 升序,大写字母按 A-Z 升序

1.1 在类内部定义比较器 – 声明为静态成员函数

class Solution {
public:
    void CharacterSort(const vector<char> e_char)
    {
      cout << "before:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;

        std::sort(e_char.begin(), e_char.end(), cmpChar);
        cout << "after:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;
    }

private:
    static bool cmpChar(const char &a, const char &b)
    {
        if (a <= 'Z' && b >= 'a')
            return false;
        else if (b <= 'Z' && a >= 'a')
            return true;
        else
            return a < b;
    }

};

输入:
vector e_char = {‘C’,‘B’,‘A’,‘c’,‘b’,‘a’};
输出:
before:
CBAcba
after:
abcABC

1.2 在函数内部定义比较器 – lamda表达式

class Solution {
public:
    void CharacterSort(const vector<char> e_char)
    {
      cout << "before:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;
        auto cmpChar = [](const char &a, const char &b) {
            if (a <= 'Z' && b >= 'a')
                return false;
            else if (b <= 'Z' && a >= 'a')
                return true;
            else
                return a < b;
        };

        std::sort(e_char.begin(), e_char.end(), cmpChar);
        cout << "after:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;
    }

1.3 全局函数比较器

using namespace std;

bool cmpChar(const char &a, const char &b)
    {
        if (a <= 'Z' && b >= 'a')
            return false;
        else if (b <= 'Z' && a >= 'a')
            return true;
        else
            return a < b;
    }

class Solution {
public:
    void CharacterSort(const vector<char> e_char)
    {
      cout << "before:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;

        std::sort(e_char.begin(), e_char.end(), cmpChar);
        cout << "after:" << endl;
        for (auto i : e_char) {
            cout << i;
        }
        cout << endl;
    }

2 重载运算符<

例子:按年月日升序排序。

2.1 在结构体中重载运算符<

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

struct date {
    int year;
    int month;
    int day;
	
	//在结构体中重载运算符<
    bool operator<(const date &a) const
    {
        // 重载<符号来比较日期的大小
        if (year == a.year) {
            if (month == a.month) {
                return day < a.day;
            } else {
                return month < a.month;
            }
        } else {
            return year < a.year;
        }
    }
};
// 在结构体外部重载运算符<
/*
bool operator<(const date &a, const date &b)
{
    // 重载<符号来比较日期的大小
    if (a.year == b.year) {
        if (a.month == b.month) {
            return a.day < b.day;
        } else {
            return a.month < b.month;
        }
    } else {
        return a.year < b.year;
    }
}
*/

int main()
{
    cout << "Hello Word!\n";

    vector<date> exam;
    exam.push_back({1997, 8, 19});
    exam.push_back({1997, 9, 30});
    exam.push_back({1990, 1, 1});
    exam.push_back({1990, 1, 20});
    cout << "before:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
    sort(exam.begin(), exam.end());
    cout << "\nafter:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
    return 0;
    };

输出:

Hello Word!
before:[1997,8,19]; [1997,9,30]; [1990,1,1]; [1990,1,20];
after:[1990,1,1]; [1990,1,20]; [1997,8,19]; [1997,9,30];

这里一定要注意一下:

参数类型如果是自定义类型,比如自己定义的结构体,类,尽管sort函数默认是从小到大排列,但是这里必须要重载比较运算符“<”!!!

2.2 在类中重载运算符<

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

class date {
public:
    int year;
    int month;
    int day;
    // 在类内部重载运算符<
    bool operator<(const date &a)
    {
        // 重载<符号来比较日期的大小
        if (year == a.year) {
            if (month == a.month) {
                return day < a.day;
            } else {
                return month < a.month;
            }
        } else {
            return year < a.year;
        }
    }
};
// 在类外部重载运算符<
/*
bool operator<(const date &a, const date &b)
{
    // 重载<符号来比较日期的大小
    if (b.year == a.year) {
        if (b.month == a.month) {
            return a.day < b.day;
        } else {
            return a.month < b.month;
        }
    } else {
        return a.year < b.year;
    }
}
*/
int main()
{
    cout << "Hello Word!\n";

    vector<date> exam;
    exam.push_back({1997, 8, 19});
    exam.push_back({1997, 9, 30});
    exam.push_back({1990, 1, 1});
    exam.push_back({1990, 1, 20});
    cout << "before:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
    sort(exam.begin(), exam.end());
    cout << "\nafter:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
        return 0;
};

在这里插入图片描述

3 重写仿函数bool operator()

sort函数的默认比较函数std:less和std::greater,内部实现就是重载了运算符()。
在这里插入图片描述

int test[10] = {4, 1, 3, 7, 5, 8, 2, 9, 6, 10};
// 注意这里创建了greater对象,sort函数调用greater对象的()运算符重载方法
sort(test, test + 10, greater<int>());

这里首先调用的是greater类默认构造方法,返回一个对象并传递给sort函数sort函数内部调用对象(a,b)时调用的是对象的运算符()重载方法来进行比较。

这里重载了()运算符其实是构造了一个“伪函数”,也就是可以把类的对象作为函数来使用。

模仿greater和less模板类的定义,我们也可以自己定义比较器类:

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;


class date {
public:
    int year;
    int month;
    int day;
};

struct MyLess  // 自定义比较器类
{
    bool operator()(const date &a, const date &b) const
    {
        if (a.year == b.year) {
            if (a.month == b.month) {
                return a.day < b.day;
            } else {
                return a.month < b.month;
            }
        } else {
            return a.year < b.year;
        }
    }
};

int main()
{
    cout << "Hello Word!\n";

    vector<date> exam;
    exam.push_back({1997, 8, 19});
    exam.push_back({1997, 9, 30});
    exam.push_back({1990, 1, 1});
    exam.push_back({1990, 1, 20});
    cout << "before:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
    sort(exam.begin(), exam.end(), MyLess());
    cout << "\nafter:";
    for (auto e : exam) {
        cout << "[" << e.year << "," << e.month << "," << e.day << "]; ";
    }
	return 0;
};

在这里插入图片描述

4 使用pair排序

头文件:

#include <utility>  #pair头文件

定义:

pair<string,int> p; 
//① 将类型定义写在前面,后面用小括号内两个元素的方式。
pair<string,int>("haha",5)
//② 使用自带的 make_pair 函数。
make_pair("haha",5)

pair<typeName1,typeName2> name,可以是任意基本数据类型或容器。

pari的排序规则默认先比较第一个元素,第一个相等比较第二个。

#include <algorithm>
#include <iostream>
#include <vector>
#include <utility>

using namespace std;

int main()
{
    cout << "Hello Word!\n";

    std::vector<std::pair<int, std::pair<int, int>>> vec;

    vec.push_back(std::make_pair(1997, std::make_pair(8, 19)));
    vec.push_back(std::make_pair(1997, std::make_pair(9, 30)));
    vec.push_back(std::make_pair(1990, std::make_pair(1, 11)));
    vec.push_back(std::make_pair(1990, std::make_pair(1, 30)));

    cout << "\nbefore:\n";
    for (auto e : vec) {
        std::cout << e.first << "," << e.second.first << "," << e.second.second << ";  ";
    }
    cout << "\nafter:\n";

    std::sort(vec.begin(), vec.end());
    for (auto e : vec) {
        std::cout << e.first << "," << e.second.first << "," << e.second.second << "; ";
    }
    cout << std::endl;
	return 0;
};

在这里插入图片描述

5 priority_queue自定义排序规则

  1. 头文件
#include <queue>
  1. 定义
priority_queue<int> a;  //对于基础类型 默认是大顶堆
priority_queue<int, vector<int>, less<int> > a;  // 等同于priority_queue<int> a 
priority_queue<int, vector<int>, greater<int> > c;  //这样就是小顶堆

priority_queue<Type, Container, Functional>
Type为数据类型; Container为保存数据的容器(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list,STL里面默认用的是vector);Functional为元素比较方式。
如果不写后两个参数,那么容器默认用的是vector,比较方式默认用operator<,也就是优先队列是大顶堆,队头元素最大。
当需要用自定义的数据类型时才需要传入这三个参数;

优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。

3 自定义排序规则
priority_queue使用自定义的数据类型,同时也要实现自定义排序规则,有2种方式:

  1. 重载运算符<
  2. 重写仿函数
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct date {
    int year;
    int month;
    int day;
    // 重载运算符<
    bool operator<(const date &a) const
    {
        // 重载<符号来比较日期的大小
        if (year == a.year) {
            if (month == a.month) {
                return day < a.day;
            } else {
                return month < a.month;
            }
        } else {
            return year < a.year;
        }
    }
};

struct myCompare  // 重写仿函数
{
    bool operator()(const date &a, const date &b) const
    {
        if (a.year == b.year) {
            if (a.month == b.month) {
                return a.day < b.day;
            } else {
                return a.month < b.month;
            }
        } else {
            return a.year < b.year;
        }
    }
};

int main()
{
    cout << "Hello Word!\n";

    priority_queue<date> vec_1;
    vec_1.push({1997, 2, 22});
    vec_1.push({1997, 2, 5});
    vec_1.push({1990, 10, 9});
    vec_1.push({1990, 8, 9});

    priority_queue<date, vector<date>, myCompare> vec_2;
    vec_2.push({2007, 2, 22});
    vec_2.push({2007, 2, 5});
    vec_2.push({2000, 10, 9});
    vec_2.push({2000, 8, 9});
    cout << "\noperator< : ";
    while (!vec_1.empty()) {
        std::cout << vec_1.top().year << ","<<vec_1.top().month<< ","<<vec_1.top().day<< ";";
        vec_1.pop();
    }

    cout << "\noperator(): ";
    while (!vec_2.empty()) {
        std::cout << vec_2.top().year << ","<<vec_2.top().month<< ","<<vec_2.top().day<< ";";
        vec_2.pop();
    }
    cout << std::endl;
    	return 0;
};

在这里插入图片描述

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

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

相关文章

部署本地GPT

在现实生活中&#xff0c;很多公司或个人的资料是不愿意公布在互联网上的&#xff0c;但是我们又要使用人工智能的能力帮我们处理文件、做决策、执行命令那怎么办呢&#xff1f;于是我们构建自己或公司的本地专属GPT变得非常重要。 先看效果&#xff1a; 查资料不用愁 家教不…

基于Java+SSM+MYSQL的助农特色农产品销售系统详细设计和实现【附源码】

基于JavaSSM助农特色农产品销售系统详细设计和实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定…

极狐GitLab 线下『 DevOps专家训练营』成都站开班在即

成都机器人创新中心联合极狐(GitLab)隆重推出极狐GitLab DevOps系列认证培训课程。该课程主要面向使用极狐GitLab的DevOps工程师、安全审计人员、系统运维工程师、系统管理员、项目经理或项目管理人员&#xff0c;完成该课程后&#xff0c;学员将达到DevOps的专家级水平&#x…

MongoDB - 整合 SpringBoot 操作全流程

目录 一、MongoDB 整合 SpringBoot 1.1、引入依赖 1.2、配置文件 1.3、集合操作 1.4、相关注解 1.5、文档操作 1.5.1、查询 1.5.2、更新 1.5.3、删除 一、MongoDB 整合 SpringBoot 1.1、引入依赖 <dependency><groupId>org.springframework.boot</grou…

Stream + Lambda生成父子树形结构

前言 在最近的开发中&#xff0c;一星期内遇到了两个类似的需求&#xff1a;返回组装好的部门树、返回组装好的地区信息树&#xff0c;最终都需要返回 List 集合对象给前端。 于是在经过需求分析和探索实践后&#xff0c;我对于这种基于 Stream 和 List 结构的父、子树形结构…

Adobe Acrobat Reader - 老牌PDF编辑器

【应用名称】&#xff1a;Adobe Acrobat Reader - 老牌PDF编辑器 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Adobe 【应用版本】&#xff1a;24.1.0 【应用大小】&#xff1a;482MB 【软件说明】&#xff1a;软件升级更新。用户将有权在手机、平板电脑…

AI嵌入式K210项目(7)-定时器

文章目录 前言一、什么是定时器&#xff1f;二、K210的timer实验过程 总结 前言 本章简单介绍下K210定时器的使用&#xff0c;实现LED灯定时闪烁的小实验&#xff1b; 一、什么是定时器&#xff1f; 简单的说&#xff0c;定时器其实是加1计数器&#xff0c;对机器周期进行计数…

【生态适配】亚信安慧AntDB数据库与契约锁完成兼容互认

日前&#xff0c;亚信安慧AntDB数据库与上海亘岩网络科技有限公司&#xff08;简称:契约锁&#xff09;研发的契约锁电子签章产品完成兼容互认。经过双方团队的严格测试&#xff0c;亚信安慧AntDB数据库与契约锁&#xff08;V4&#xff09;完全兼容&#xff0c;整体运行稳定高效…

图像处理------亮度

from PIL import Imagedef change_brightness(img: Image, level: float) -> Image:"""按照给定的亮度等级&#xff0c;改变图片的亮度"""def brightness(c: int) -> float:return 128 level (c - 128)if not -255.0 < level < 25…

未来能源转型之路:2023年第十三届中国国际储能大会启示录

在2023年第十三届中国国际储能大会上&#xff0c;全球各地的能源专家、学者和企业代表齐聚一堂&#xff0c;共同探讨了储能技术在推动能源转型中的重要作用。对于我们普通人来说&#xff0c;从这场大会中可以学到什么呢&#xff1f; 一、储能技术是未来能源发展的关键 随着可再…

Alibaba-> EasyExcel 整理3

1 导入依赖 <!-- easyExcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version >3.2.1</version><exclusions><exclusion><artifactId>poi-ooxml-schemas</art…

微信小程序-----全局配置与页面配置

目录 前言 全局配置文件 一、window 1. 小程序窗口的组成部分 2. window 节点常用的配置项 3. 设置导航栏的标题 4. 设置导航栏的背景色 5. 设置导航栏的标题颜色 6. 全局开启下拉刷新功能 7. 设置下拉刷新时窗口的背景色 8. 设置下拉刷新时 loading 的样式 9. 设置…

网站防御爬虫攻击有哪些方式

很多网站都深受爬虫困扰&#xff0c;网站在被爬虫大量抓取的的时候经常容易被爬虫把服务器资源抓崩了&#xff0c;有的时候&#xff0c;同行也会来爬取我们网站进行数据采集&#xff0c;影响我们站点的原创性&#xff0c;那么如何进行相对应的防护还是非常重要的&#xff01; …

Python数据分析案例33——新闻文本主题多分类(Transformer, 组合模型) 模型保存

案例背景 对于海量的新闻&#xff0c;我们可能需要进行文本的分类。模型构建很重要&#xff0c;现在对于自然语言处理基本都是神经网络的方法了。 本次这里正好有一组质量特别高的新闻数据&#xff0c;涉及 教育 科技 社会 时政 财经 房产 家居 七大主题&#xff0c;基本涵盖…

IDEA 在本地启动多个 SpringBoot 后端服务模拟集群

目录 方式一&#xff1a;使用 IDEA 界面在多个后端端口运行同一个项目 方式二&#xff1a;通过控制台在运行项目 jar 包时传入端口配置 方式一&#xff1a;使用 IDEA 界面在多个后端端口运行同一个项目 1. 点击 Run / Debug 在默认端口启动项目 2. 点击 Services&#xff0…

企业网络扫描程序中需要的功能

网络扫描程序已成为每个 IT 管理员抵御安全漏洞的第一道防线不可或缺的一部分。使用正确的网络扫描程序工具进行有效的网络侦察和诊断&#xff0c;使管理员能够查明可能升级为安全风险和网络事故的网络问题。典型的网络扫描程序可以与 IP 扫描程序配合使用&#xff0c;按顺序扫…

深度学习笔记(二)——Tensorflow环境的安装

本篇文章只做基本的流程概述&#xff0c;不阐述具体每个软件的详细安装流程&#xff0c;具体的流程网上教程已经非常丰富。主要是给出完整的安装流程&#xff0c;以供参考 环境很重要 一个好的算法环境往往能够帮助开发者事半功倍&#xff0c;入门学习的时候往往搭建好环境就已…

Nvidia-docker的基础使用方法

安装&#xff1a; 安装nvidia-docker&#xff1a; distribution$(. /etc/os-release;echo $ID$VERSION_ID)curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.l…

指定Top名校|管理学教师拜师香港理工大学院士麾下访学

X老师拟自费赴香港访学&#xff0c;并指定了香港Top5之内的高校。申请一个月后&#xff0c;我们落实了香港理工大学的访学职位&#xff0c;导师为香港工程科学院和国际系统与控制科学院的两院院士、讲座教授。 X老师背景&#xff1a; 申请类型&#xff1a;自费访问学者 工作背…

spring boot学习第八篇:通过spring boot、jedis实现秒单

参考&#xff1a;Redis实现分布式锁的7种方案 - 知乎 1、 准备数据库表&#xff0c;如下SQL表示库存表&#xff0c;有主键ID和库存数量字段 CREATE TABLE t_stock (id bigint(20) NOT NULL AUTO_INCREMENT,quantity bigint(20) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEF…