当前位置 : 主页 > 编程语言 > c语言 >

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

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 正文 创建过程中的排序 创建升序 创建降序 生成一个范围的降序 通过键比较两个元素 key_compare key_comp() const value_compare value_comp() const 对用初始化器列表创建的地图进行排序 结论
目录
  • 正文
  • 创建过程中的排序
  • 创建升序
  • 创建降序
  • 生成一个范围的降序
  • 通过键比较两个元素
    • 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++地图按键排序的资料请关注自由互联其它相关文章!

      上一篇:C语言实现学生信息管理系统开发
      下一篇:没有了
      网友评论