C++中地图按键排序实现示例

目录
  • 正文
  • 创建过程中的排序
  • 创建升序
  • 创建降序
  • 生成一个范围的降序
  • 通过键比较两个元素
    • key_compare key_comp() const
    • value_compare value_comp() const
  • 对用初始化器列表创建的地图进行排序
  • 结论

正文

一个地图由键/值对组成。每一对都是一个元素。一个地图中的所有键都是唯一的。一个地图可以按键进行排序。排序可以是升序或降序。升序是默认的。地图中的排序并不总是直接的。它需要一个比较函数对象。如果比较对象被忽略了,就会发生默认的排序。

如果键是恒定的指向字符的指针,地图就会按键的指针排序,而不是按键的字符串字数排序。这几乎不是任何人想要的。考虑以下水果的键/值对和它们的外部颜色。

    "plum" => "purple"
    "blackberry" => "dark blue-black"
    "watermelon" => "green"
    "apricot", => "orange"
     "papaya" => "orange"
    "banana" => "yellow"

水果是键,而颜色是值。这个元素列表(键/值对)是没有排序的。下面的程序创建了这个列表的映射,并按原样显示,没有按字符串字面排序。

 #include <iostream>
    #include <map>
    using namespace std;
    int main()
    {
        map<const char*, const char*> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        for (map<const char*, const char*>::iterator it = mp.begin(); it != mp.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是:

plum => purple
    blackberry => dark blue-black
    watermelon => green
    apricot => orange
    papaya => orange
    banana => yellow

未按字符串字面排序,但按指针排序。要在C++程序中使用地图,必须用include指令来包含地图库。

创建上述简单地图的另一种方法是如下。

 #include <iostream>
    #include <map>
    using namespace std;
    int main()
    {
        map<const char*, const char*> mp({{"plum","purple"}, {"blackberry","dark blue-black"}, {"watermelon","green"}, {"apricot","orange"}, {"papaya","orange"}, {"banana","yellow"}});
        for (map<const char*, const char*>::iterator it = mp.begin(); it != mp.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是:

plum => purple
    blackberry => dark blue-black
    watermelon => green
    apricot => orange
    papaya => orange
    banana => yellow

未按字符串字面排序,但按指针排序。如果键值是整数,输出将按键值排序。在实践中,许多地图的键是字符串字面。这篇文章解释了字符串字面的键是如何对地图进行排序的。

创建过程中的排序

构建地图的完整模板是:

template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class map;

类,Compare和Allocator,有默认值。也就是说,它们有默认的专业化,不必在map声明(实例化)中进行类型化。这里要关注的是比较类。这个类的名字是Compare,默认的特殊化是 "less"。"less<Key "意味着按升序排序。另一个选项是 "greater",意思是降序排序。

一个地图在创建时通常是按键值排序的。如果键是const char*,那么指向引号字面字符串的指针将被排序,而不是字面文本。要在创建过程中把字符串作为键进行排序,字符串必须是由字符串类实例化的字符串对象的字面意思。这意味着必须包括字符串库和地图库。

创建升序

在下面的程序中,地图被创建,升序排序。

 #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<string, const char*, less<string>> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        for (map<string, const char*>::iterator it = mp.begin(); it != mp.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是:

apricot => orange
    banana => yellow
    blackberry => dark blue-black
    papaya => orange
    plum => purple
    watermelon => green

即使模板中省略了less,排序仍然会是升序的,因为less是默认的。

创建降序

为了创建一个地图,使其按键的降序排序,必须对比较专业化进行编码。下面的程序说明了这一点。

 #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<string, const char*, greater<string>> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        for (map<string, const char*>::iterator it = mp.begin(); it != mp.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是:

watermelon => green
    plum => purple
    papaya => orange
    blackberry => dark blue-black
    banana => yellow
    apricot => orange

生成一个范围的降序

一个地图的范围可以按降序产生。这涉及到创建第二个地图,它是第一个地图的一个范围。下面的程序说明了这一点。

 #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<string, const char*> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        map<string, const char*>::iterator itB = mp.begin();
        itB++;
        map<string, const char*>::iterator itE = mp.end();
        itE--;
        map<string, const char*, greater<string>> mpR(itB, itE);
        for (map<string, const char*>::iterator it = mpR.begin(); it != mpR.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是:

plum => purple
    papaya => orange
    blackberry => dark blue-black
    banana => yellow

第一个地图对象有六个元素,分别是

apricot => orange
    banana => yellow
    blackberry => dark blue-black
    papaya => orange
    plum => purple
    watermelon => green

考虑的范围是:

 banana => yellow
    blackberry => dark blue-black
    papaya => orange
    plum => purple
    watermelon => green

在代码中,"itB++"指向{"香蕉","黄色"},"itE-"指向{"西瓜","绿色"}的范围。在C++中处理一个范围时,最后一个元素不参与操作。于是,输出有四个元素,{"西瓜","绿"}被省略了。

第二个map的Compare模板参数的特化是 greater。如果它是less或者省略,那么这个范围会导致升序。

通过键比较两个元素

key_compare key_comp() const

这个成员函数返回map容器用来比较键的比较对象的副本。比较对象是一个函数对象。它将把两个键作为参数,如果左键小于右键,则返回真。有了这个,代码段应该是。

 key_compare kc = mp.key_comp();
 bool bl = kc("watermelon", "apricot");

key_compare不被编译器识别。在这个代码段中消除key_compare,在第二条语句中替换掉kc,结果是。

bool bl = mp.key_comp()("watermelon", "apricot");

下面的程序说明了key_comp()的使用。

#include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<string, const char*> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        bool bl = mp.key_comp()("watermelon", "apricot");
        cout << bl << endl;
        return 0;
    }

输出结果是0,表示错误。

上述代码段的真正问题是,key_compare的命名空间没有得到很好的表达。如果这段代码是

 map<string, const char*>::key_compare kc = mp.key_comp();
 bool bl = kc("watermelon", "apricot");

它本来可以工作(被编译器接受)。

value_compare value_comp() const

这个成员函数与key_comp()类似。注意:这里指的不是键/值对的值,而是键/值对的元素。所以,value_compare函数对象的两个参数是迭代器元素。下面的程序使用value_comp(),在比较第一个和最后一个元素,{"杏","橙"}和{"西瓜","绿"}:

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<string, const char*, less<string>> mp;
        mp["plum"] = "purple";
        mp["blackberry"] = "dark blue-black";
        mp["watermelon"] = "green";
        mp["apricot"] = "orange";
        mp["papaya"] = "orange";
        mp["banana"] = "yellow";
        map<string, const char*>::iterator itB = mp.begin();
        map<string, const char*>::iterator itE = mp.end();
        itE--;
        map<string, const char*>::value_compare vc = mp.value_comp();
        bool bl = vc(*itB, *itE);
        cout << bl << endl;
        return 0;
    }

输出是1,表示真。迭代器itB和itE被解读为有它们的元素,用的是嵌套运算符。

对用初始化器列表创建的地图进行排序

在下面的程序中,排序是降序的,键是字符串对象,从字符串类实例化出来。

    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    int main()
    {
        map<string, const char*, greater<string>> mp({{"plum","purple"}, {"blackberry","dark blue-black"}, {"watermelon","green"}, {"apricot","orange"}, {"papaya","orange"}, {"banana","yellow"}});
        for (map<string, const char*>::iterator it = mp.begin(); it != mp.end(); it++)
            cout << it->first << " => " << it->second << endl;
        return 0;
    }

输出结果是。

watermelon => green
    plum => purple
    papaya => orange
    blackberry => dark blue-black
    banana => yellow
    apricot => orange

结论

一个地图的创建是按照键来排序的,升序。升序是默认的顺序。要想让它降序,请在模板参数列表中加入模板参数的特殊化,即作为第三个参数的大号。注意:如果键值是字符串,它们必须从字符串类中实例化出来,如上图所示。作为const-char*或char-arr[]的字符串键,其指针最终会被排序,而不是其字面意义。

以上就是C++中地图按键排序实现示例的详细内容,更多关于C++地图按键排序的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++中map和set的简介及使用详解

    目录 关联式容器 键值对 set set的介绍 set的使用 multiset map map的介绍 map的使用 map构造 map的插入 map的[]运算符重载 multiset 关联式容器 关联式容器包括序列式容器和关联式容器 序列式容器: 底层为线性序列的数据结构,里面存储的是元素本身,包含vector.list.deque.forward_list(C++11)等.关联式容器: 里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高,包含set.map.u

  • C++可视化角色按键移动控制的实现

    1.新建项目 新建一个空项目,并添加一个源文件(.cpp) 记住.cpp文件所在的位置 2.新建一个窗口,并添加背景图片 将要使用的图片,拷贝到项目所在文件夹 与.cpp文件处于同一文件夹 #include<stdio.h> //用于标准输入输出 #include<graphics.h> //用于图形的函数库 int main() { initgraph(1440, 768); //创建一个窗口,大小设定为背景大小,以免图片拉伸变形 IMAGE background; //创建一个

  • c++ 数据结构map的使用详解

    map的常用用法 map 表示映射,可以将任何基本类型(包括 STL 容器)映射到任何基本类型(包括 STL 容器),例如可以建立如 int 到 double,string 到 int 的映射等. map 提供一对一的 hash,该功能类似 Python 的字典: 第一个称为键( key ),每个关键字只能在 map 中出现一次: 第二个称为该键的值( value ): 1. 头文件 <bits/stdc++.h> 头文件已经包括了该头文件. 2. 定义 定义 map 如下,参数的第一个为 k

  • C++模拟键盘按键的实例

    这个与模拟鼠标点击的函数差不多,直接上函数 keybd_event(VK_RETURN,0,0,0); keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0); 这是模拟按下.抬起回车键 我直接上一个我曾经用它与一些函数写的一个刷屏程序 我用自己的小号试过,如果对方用的是手机,效果很显著 #include<iostream> #include<windows.h> using namespace std; int b[11000],top=0; cha

  • C++中地图按键排序实现示例

    目录 正文 创建过程中的排序 创建升序 创建降序 生成一个范围的降序 通过键比较两个元素 key_compare key_comp() const value_compare value_comp() const 对用初始化器列表创建的地图进行排序 结论 正文 一个地图由键/值对组成.每一对都是一个元素.一个地图中的所有键都是唯一的.一个地图可以按键进行排序.排序可以是升序或降序.升序是默认的.地图中的排序并不总是直接的.它需要一个比较函数对象.如果比较对象被忽略了,就会发生默认的排序. 如果键

  • DoytoQuery中的分页排序方案示例详解

    目录 引言 分页 分页接口 排序 请求对象 响应对象 小结 引言 分页和排序是数据库提供的两项基本的查询功能. 以MySQL为例,一条典型的SQL查询语句如下: SELECT * FROM t_user ORDER BY create_time DESC, username ASC LIMIT 10 OFFSET 20 那么在前后端交互中,前端应该如何向后端传递分页和排序有关的信息呢?需要传递哪些参数?参数的意义和格式又是什么? 分页 分页的语句为LIMIT 10 OFFSET 20,其中10为

  • java中实现Comparable接口实现自定义排序的示例

    实例如下所示: class Student implements Comparable{ String name; int gpa; @Override public int compareTo(Object arg0) { // TODO Auto-generated method stub Student s = (Student)arg0; if(gpa == s.gpa) return name.compareTo(s.name); else if(gpa < s.gpa) return

  • python中字典按键或键值排序的实现代码

    字典排序 在程序中使用字典进行数据信息统计时,由于字典是无序的所以打印字典时内容也是无序的.因此,为了使统计得到的结果更方便查看需要进行排序.Python中字典的排序分为按"键"排序和按"值"排序. 按"值"排序 按"值"排序就是根据字典的值进行排序,可以使用内置的sorted()函数. sorted(iterable[, cmp[, key[, reverse]]]) iterable:是可迭代类型类型; cmp:用于比较的

  • Python将列表中的元素转化为数字并排序的示例

    本文实例讲述了Python中列表元素转为数字的方法.分享给大家供大家参考,具体如下: 有一个数字字符的列表: numbers = ['2', '4', '1', '3'] 想要把每个元素转换为数字: numbers = [2, 4, 1, 3] 1. Python2.x,可以使用map函数: numbers = map(int, numbers) 2. Python3.x,map返回的是map对象,当然也可以转换为List: numbers = list(map(int, numbers)) 排

  • MySQL中utf8mb4排序规则示例

    在MySQL中常见的utf8mb4排序规则有: utf8mb4_0900_ai_ci utf8mb4_unicode_ci utf8mb4_general_ci 当设置表的默认字符集为utf8mb4字符集但未明确指定排序规则时: 在MySQL 5.7版本中,默认排序规则为utf8mb4_general_ci. 在MySQL 8.0版本中,默认排序规则为utf8mb4_0900_ai_ci. 由于utf8mb4_0900_ai_ci排序规则时MySQL 8.0引入的排序规则,因此将MySQL 8.

  • shell中的排序算法示例代码

    目录 冒泡排序法 基本思想: 算法思路 直接选择排序 基本思想: 反转排序 基本思想: 直接插入算法 基本思想: 希尔算法 基本思想 冒泡排序法 类似旗袍上涌的动作,会将数据在数组中从小大大或者从大到小不断的向前移动. 基本思想: 冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部. 算法思路 冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要

  • GO语言中常见的排序算法使用示例

    目录 快排 冒泡 选择排序 插入排序 希尔排序 二分法查找 快排 package main import ( "fmt" "math/rand" "time" ) func main() { li:=[]int{1,3,5,2,4,6,9,7} left:=0 right:=len(li)-1 fmt.Println(quick_sort(li,left,right)) } func quick_sort(li []int, left,right

  • Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例

    本文实例讲述了Python实现对不原生支持比较操作的对象排序算法.分享给大家供大家参考,具体如下: 问题:想在同一个类的实例之间做排序,但是它们并不原生支持比较操作. 解决方案:使用内建的sorted()函数可接受一个用来传递可调用对象的参数key,sorted利用该可调用对象返回的待排序对象中的某些值来比较对象. from operator import attrgetter class User: def __init__(self, user_id): self.user_id = use

  • Python cookbook(数据结构与算法)通过公共键对字典列表排序算法示例

    本文实例讲述了Python通过公共键对字典列表排序算法.分享给大家供大家参考,具体如下: 问题:想根据一个或多个字典中的值来对列表排序 解决方案:利用operator模块中的itemgetter()函数对这类结构进行排序是非常简单的. # Sort a list of a dicts on a common key rows = [ {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Be

随机推荐