首页 > 编程语言 >【转】c++中Vector等STL容器的自定义排序

【转】c++中Vector等STL容器的自定义排序

时间:2023-01-25 17:44:38浏览次数:54  
标签:TItem stItem2 自定义 STL i32Type c++ stItemVec i32ID stItem1

三种方式实现vector的自定义排序

方法1:重载运算符

#include <vector>
 #include <algorithm>
 #include <functional>
 
using namespace std;
struct TItem
{
    int m_i32Type;
    int m_i32ID;
 
    bool operator <(const TItem& rhs) const // 升序排序时必须写的函数
    {
        return m_i32Type < rhs.m_i32Type;
    }
    bool operator >(const TItem& rhs) const // 降序排序时必须写的函数
    {
        return m_i32Type > rhs.m_i32Type;
    }
};
int main()
{
    vector<TItem> stItemVec;
 
 
    TItem stItem1;
    stItem1.m_i32Type = 1;
    stItem1.m_i32ID = 1;
 
    TItem stItem2;
    stItem2.m_i32Type = 2;
    stItem2.m_i32ID = 2;
 
    TItem stItem3;
    stItem3.m_i32Type = 3;
    stItem3.m_i32ID = 3;
 
    TItem stItem4;
    stItem4.m_i32Type = 2;
    stItem4.m_i32ID = 4;
 
    stItemVec.push_back(stItem1);
    stItemVec.push_back(stItem2);
    stItemVec.push_back(stItem3);
    stItemVec.push_back(stItem4);
 
    // 升序排序
    sort(stItemVec.begin(), stItemVec.end(), less<TItem>());
    // 或者sort(ctn.begin(), ctn.end());   默认情况为升序
 
    for (size_t i = 0; i < stItemVec.size(); i++)
        printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
 
    printf("--\n");
 
    // 降序排序
    sort(stItemVec.begin(), stItemVec.end(), greater<TItem>());
 
    for (size_t i = 0; i < stItemVec.size(); i++)
        printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
 
    return 0;
}

方法2:全局的比较函数


#include <vector>
 #include <algorithm>
 #include <functional>
  
 
using namespace std;
  
 
struct TItem
 {
     int m_i32Type;
     int m_i32ID;
 };
  
 
bool lessmark(const TItem& stItem1, const TItem& stItem2)
 {
     return stItem1.m_i32Type < stItem2.m_i32Type;
 }
  
 
bool greatermark(const TItem& stItem1, const TItem& stItem2)
 {
     return stItem1.m_i32Type > stItem2.m_i32Type;
 }
  
 
int main()
 {
     vector<TItem> stItemVec;
  
 
    TItem stItem1;
     stItem1.m_i32Type = 1;
     stItem1.m_i32ID = 1;
  
 
    TItem stItem2;
     stItem2.m_i32Type = 2;
     stItem2.m_i32ID = 2;
  
 
    TItem stItem3;
     stItem3.m_i32Type = 3;
     stItem3.m_i32ID = 3;
  
 
    TItem stItem4;
     stItem4.m_i32Type = 2;
     stItem4.m_i32ID = 4;
  
 
    stItemVec.push_back(stItem1);
     stItemVec.push_back(stItem2);
     stItemVec.push_back(stItem3);
     stItemVec.push_back(stItem4);
  
 
    sort(stItemVec.begin(), stItemVec.end(), lessmark); //升序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
  
 
    printf("--\n");
  
 
    sort(stItemVec.begin(), stItemVec.end(), greatermark); //降序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
  
 
    return 0;
 }

方法3:函数对象

#include <vector>
 #include <algorithm>
 #include <functional>
  
 
using namespace std;
  
 
struct TItem
 {
     int m_i32Type;
     int m_i32ID;
 };
  
 
class CompLess
 {
 public:
     bool operator ()(const TItem& stItem1, const TItem& stItem2)
     {
         return stItem1.m_i32Type < stItem2.m_i32Type;
     }
 };
  
 
class CompGreater
 {
 public:
     bool operator ()(const TItem& stItem1, const TItem& stItem2)
     {
         return stItem1.m_i32Type > stItem2.m_i32Type;
     }
 };
  
 
int main()
 {
     vector<TItem> stItemVec;
  
 
    TItem stItem1;
     stItem1.m_i32Type = 1;
     stItem1.m_i32ID = 1;
  
 
    TItem stItem2;
     stItem2.m_i32Type = 2;
     stItem2.m_i32ID = 2;
  
 
    TItem stItem3;
     stItem3.m_i32Type = 3;
     stItem3.m_i32ID = 3;
  
 
    TItem stItem4;
     stItem4.m_i32Type = 2;
     stItem4.m_i32ID = 4;
  
 
    stItemVec.push_back(stItem1);
     stItemVec.push_back(stItem2);
     stItemVec.push_back(stItem3);
     stItemVec.push_back(stItem4);
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompLess()); //升序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
  
 
    printf("--\n");
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompGreater()); //降序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i].m_i32Type, stItemVec[i].m_i32ID);
  
 
    return 0;
 }
  
/*
 结果如下:
 type: 1, id: 1
 type: 2, id: 2
 type: 2, id: 4
 type: 3, id: 3
 --
 type: 3, id: 3
 type: 2, id: 2
 type: 2, id: 4
 type: 1, id: 1
 可以看出vector的sort的稳定的。
 */

问题:

1,示例代码中只有>和<关系处理,==关系是如何推导出来的?
2,排序时要移动元素,效率怎样?
3,如果自定义结构定义在一个类的内部,使用函数对象进行排序,这个函数对象可以作为类的成员函数吗?
4,在上面的例子中,vector中存放的都是结构(对象)本身,如果存放的是结构指针,该如何排序呢?此时只能通过全局的比较函数或者函数对象来做,且比较函数的参数要是指针类型的,如下:

(1)全局的比较函数

#include <vector>
 #include <algorithm>
 #include <functional>
  
 
using namespace std;
  
 
struct TItem
 {
     int m_i32Type;
     int m_i32ID;
 };
  
 
bool CompLess(const TItem* pstItem1, const TItem* pstItem2)
 {
     return pstItem1->m_i32Type < pstItem2->m_i32Type;
 }
  
 
bool CompGreater(const TItem* pstItem1, const TItem* pstItem2)
 {
     return pstItem1->m_i32Type > pstItem2->m_i32Type;
 }
  
 
int main()
 {
     vector<TItem*> stItemVec;
  
 
    TItem stItem1;
     stItem1.m_i32Type = 1;
     stItem1.m_i32ID = 1;
  
 
    TItem stItem2;
     stItem2.m_i32Type = 2;
     stItem2.m_i32ID = 2;
  
 
    TItem stItem3;
     stItem3.m_i32Type = 3;
     stItem3.m_i32ID = 3;
  
 
    TItem stItem4;
     stItem4.m_i32Type = 2;
     stItem4.m_i32ID = 4;
  
 
    stItemVec.push_back(&stItem1);
     stItemVec.push_back(&stItem2);
     stItemVec.push_back(&stItem3);
     stItemVec.push_back(&stItem4);
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompLess); //升序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i]->m_i32Type, stItemVec[i]->m_i32ID);
  
 
    printf("--\n");
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompGreater); //降序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i]->m_i32Type, stItemVec[i]->m_i32ID);
  
    return 0;
 }

(2)函数对象


#include <vector>
 #include <algorithm>
 #include <functional>
  
 
using namespace std;
  
 
struct TItem
 {
     int m_i32Type;
     int m_i32ID;
 };
  
 
class CompLess
 {
 public:
     bool operator ()(const TItem* pstItem1, const TItem* pstItem2)
     {
         return pstItem1->m_i32Type < pstItem2->m_i32Type;
     }
 };
  
 
class CompGreater
 {
 public:
     bool operator ()(const TItem* pstItem1, const TItem* pstItem2)
     {
         return pstItem1->m_i32Type > pstItem2->m_i32Type;
     }
 };
  
 
int main()
 {
     vector<TItem*> stItemVec;
  
 
    TItem stItem1;
     stItem1.m_i32Type = 1;
     stItem1.m_i32ID = 1;
  
 
    TItem stItem2;
     stItem2.m_i32Type = 2;
     stItem2.m_i32ID = 2;
  
 
    TItem stItem3;
     stItem3.m_i32Type = 3;
     stItem3.m_i32ID = 3;
  
 
    TItem stItem4;
     stItem4.m_i32Type = 2;
     stItem4.m_i32ID = 4;
  
 
    stItemVec.push_back(&stItem1);
     stItemVec.push_back(&stItem2);
     stItemVec.push_back(&stItem3);
     stItemVec.push_back(&stItem4);
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompLess()); //升序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i]->m_i32Type, stItemVec[i]->m_i32ID);
  
 
    printf("--\n");
  
 
    sort(stItemVec.begin(), stItemVec.end(), CompGreater()); //降序排序
  
 
    for (size_t i = 0; i < stItemVec.size(); i++)
         printf("type: %d, id: %d\n", stItemVec[i]->m_i32Type, stItemVec[i]->m_i32ID);
  
 
    return 0;
 }

原文链接:https://www.cnblogs.com/wengzilin/p/3937491.html

标签:TItem,stItem2,自定义,STL,i32Type,c++,stItemVec,i32ID,stItem1
From: https://www.cnblogs.com/xiaohai123/p/17067100.html

相关文章

  • c++学习日记day1 1/25
    B.超重青蛙题目描述在青蛙王国,每个青蛙有着不同的体重。给出一组青蛙的体重,计算里面超出平均体重的青蛙数量。 输入第一行输入参数T,表示有T个测试实例第二行输入......
  • pages.json 文件:自定义导航栏
    自定义导航栏使用注意当navigationStyle设为custom或titleNView设为false时,原生导航栏不显示,此时要注意几个问题:非H5端,手机顶部状态栏区域会被页面内容覆盖。这是因为窗......
  • C++指针类型的局部变量初始化
    编译器一般不会对一般变量进行初始化,当然也包括指针。所以负责初始化指针变量的只有程序员自己。使用未初始化的指针是相当危险的。因为指针直接指向内存空间,所以程序员很......
  • wireshark 中使用lua解析自定义协议
    简述利用wireshark+lua实现自定义协议实时解析,保存分析结果1.找到版本和init.lua的位置:C:\ProgramFiles\Wireshark    2.修改init.lua(该版本是默认打开的,......
  • C++ 单例模式最佳实践
    单例模式有很多种实现:懒汉/饿汉非线程安全线程安全每次判空加锁(效率不高)DCL:Double-checklock(繁琐,C++11之前的最佳实现)Meyers’singleton:静态变量(简洁,C++11之后......
  • C++ 实现复制赋值运算符重载
    考察点返回值类型MyClass&,可以连续赋值参数类型:(constMyClass&rhs)或者(MyClassrhs)值传递(copy-swap)自赋值安全无内存泄漏,旧值需要析构异常安全参考实现c......
  • 【奇妙的数据结构世界】 用经典例题对数组进行全面分析 | C++
    ​​​​​​第八章  数组:::hljs-center目录第八章数组●前言●一、数组是什么?1.简要介绍2.具体情况●二、数组典型例题——一维&二维&三维1.一维数组......
  • C/C++ 单链表的实现(初始化、插入、删除、销毁)
    #include<iostream>#include<Windows.h>#defineMAX_SIZE100usingnamespacestd;//单链表typedefstruct_LinkList{intdata;//数据域struct_LinkL......
  • Docker 容器添加自定义root ca
    比如如果我们基于了step-ca工具做为我们的ca机制,就会有不可信的问题,业务使用就特别不方便了,以下是一个参考配置实际上很简单就是使用update-ca-certificates更新信息......
  • 自定义指令
               ......