• Practice6_2_map_sort_by_comparator


    上一个程序初步简单的实现了使用自定义operator的方式的map的初始化,但是遇到了一个问题:

    检查operator函数时报“invalid operator<”错误,程序崩了。下午找出原 
    因。下一个程序中解决该问题,并实现高内聚。

    “invalid operator<”错误的原因是(具体见这里):

    在待排序列中如果出现相等元素,则会报错Expression : invalid operator < 

    原因是,c++编译器检测到调用cmp的参数a==b时,c++编译器会立即用反序参数调用cmp函数,即调用cmp(b,a),来判断cmp函数是否已经执行了严格的弱序规则(a与b相等则位置不被改变)

    于是,重新实现operator中的条件判断及返回值,这两点就是解决问题的关键。调试通过,程序能正常运行。

    // Practice6_map_sort_by_comparator.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <map>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    typedef struct tagStudentInfo
    {
           int      stuId;
           string   stuName;
    }StudentInfo; 
    
    /* 两种方式实现操作符函数,一种是struct,另一种是class加public
    struct CompareStu
    {
        int operator()(const StudentInfo &x, const StudentInfo &k) const
        {
            if(k.stuId > x.stuId) return 1;//这里必须是大于,并且return true,原因见参考链接
            else return x.stuName.compare(k.stuName) > 0;
      }
    };*/
    
    /* 另一种是class加public
    class CompareStu
    {
    public:
        int operator()(const StudentInfo &x, const StudentInfo &k) const
        {
            if(k.stuId > x.stuId) return 1;//这里必须是大于,并且return true,原因见参考链接
            else return x.stuName.compare(k.stuName) > 0;
      }
    };*/
    
    /* 上面的两种实现在使用for循环insert数据时是有问题的,主要在于两元素相等时的返回值,下面这种可编译通过*/
    class CompareStu
    {
    public:
        int operator()(const StudentInfo &x, const StudentInfo &k) const
        {
            if(k.stuId != x.stuId) 
                return k.stuId > x.stuId;//这里必须是大于,并且return true,原因见参考链接
            else 
                return k.stuName.compare(x.stuName) > 0;
      }
    };
    
    /* 第一种初始化方式*/
    void initMap( map<StudentInfo, int, CompareStu> &mapStu)
    {
         StudentInfo studentInfo;
         studentInfo.stuId = 1;
         studentInfo.stuName = "student_one";
         mapStu.insert(pair<StudentInfo, int>(studentInfo, 90));
         studentInfo.stuId = 2;
         studentInfo.stuName = "student_two";
         mapStu.insert(pair<StudentInfo, int>(studentInfo, 80));
    }
    
    string strs[5] = {"huawei", "xiaomi", "meizu", "oppo", "vivo"};
    /* 第二种初始化方式*/
    void initMapByPair(map<StudentInfo, int, CompareStu> &mapStu, unsigned int size)
    {
        StudentInfo si = {0, ""}; //两种方式实现StudentInfo的初始化,一种是先声明后赋值,另一种直接在循环中初始化。不能混用!!为啥??
        for(unsigned int i = 0; i < size; i++)
        {
            si.stuId = i + 1;
            si.stuName = strs[i];
            mapStu.insert(pair<StudentInfo, int>(si, i + 90));
        }
    }
    
    void printMap(map<StudentInfo, int, CompareStu> mapStu)
    {
            map<StudentInfo, int, CompareStu>::iterator iter= mapStu.begin();
            for(; iter != mapStu.end(); iter++)
            {
                cout << iter->first.stuId << "," << iter->first.stuName << "," << iter->second << endl;
            }
    }
    
    int main()
    {
           map<StudentInfo, int, CompareStu> mapStudent;
          //initMap(mapStudent);
           initMapByPair(mapStudent, 5);//第二种初始化方式
    
            printMap(mapStudent);
    }

    运行结果:

    1,huawei,90
    2,xiaomi,91
    3,meizu,92
    4,oppo,93
    5,vivo,94

  • 相关阅读:
    sizeof运算符介绍以及常见的坑
    程序员面试需要带身份证和毕业证原件吗
    CentOS7配置rsync实现文件同步
    CentOS7配置samba共享文件系统
    freecplus框架-字符串操作
    freecplus框架-文件操作
    freecplus框架-日志文件操作
    freecplus框架-日期、时间和计时器
    Unix 网络编程卷一源码编译踩坑记录 ubtutu 19.10
    实时人流量监测——海康威视sdk初体验
  • 原文地址:https://www.cnblogs.com/liuzc/p/6502497.html
Copyright © 2020-2023  润新知