如何更改地图容器的内部排序方案?

时间:2016-02-06 22:24:17

标签: c++ dictionary containers

我是初学者C ++程序员,因此有些语言结构我不明白会阻止我理解map的API(供你参考,here

更重要的是,有些问题:

如何更改地图的内部排序方案,以便在我们使用map::<string, ...>时,键值按字母顺序排序?

更具体地说是关于map::key_comp,它是一个定义和遗忘的东西,一旦我们定义了相同类型的两个元素对“不等(一个小于另一个)”意味着什么,然后内部和自动完成排序 - 所以我们需要插入键/值对?或者我们是否必须定义相等/排序然后显式调用函数以返回一个布尔来实现有序插入?

2 个答案:

答案 0 :(得分:5)

以下是如何为有序地图提供模板参数以使用非默认排序的示例:

std::map<int, int, std::greater<int> > m;

取自C++ std::map items in descending order of keys

另外,对于更复杂的示例:how to declare custom sort function on std::map declaration?

答案 1 :(得分:0)

[解决]我选择的解决方案

假设您的地图是:map<int,vector<int>,compAB> myMap;

然后你需要做两件事来定义“compAB”:

定义一个返回true或false /(或1或0)的比较函数。我还没有测试过这个函数是否可以带多个参数(虽然我不知道为什么它只能返回一个bool。这个函数应该指定你打算如何订购两个相同的对象在地图中输入key值。

bool compare(int a, int b)
{
    if(a < b) return true; 
    return false; //Default
}

map :: key_comp对象的API(here表示如果第一个参数是“小于”/“在第二个参数之前,则比较函数需要返回true。否则返回false资源)。在这里,我使用了一个简单的标准来确定“小于”:如果a&lt; b,则在b之前,因为计算机会对其进行评估。

创建一个结构,其成员只包含一个operator-overload:

struct compAB
{
   bool operator()(int i1, int i2){
      return compare(i1, i2); 
   }
};

然后,您可以发出声明:map<int,vector<int>,compAB> myMap;并且对inserted()的任何调用都将根据您指定的键排序方案插入您指定的对

例如:

#include <iostream> 
#include <map> 

bool compare_descend(int a, int b)
{
    //specifies that when a>b return true -> a FOLLOWS b
    if(b < a) return true; 
    return false; 
}

bool compare_ascend(int a, int b)
{
    //specifies that when a<b return true -> a PRECEDES b
    if(a < b) return true; 
    return false; //Default
}

struct comp_asc
{
   bool operator()(int i1, int i2)
   {
     return compare_ascend(i1, i2); 
   }
};


int main()
{   
    std::cout << "int_map_asc: [key,value]\n"; 

    //Map declaration via class function
    std::map<int,std::string,comp_asc> int_map_asc; 

    //Insert pairs into the map
    int_map_asc.insert( std::pair<int,std::string>(0, "Alan") );
    int_map_asc.insert( std::pair<int,std::string>(1, "Baye") );
    int_map_asc.insert( std::pair<int,std::string>(2, "Carl") );
    int_map_asc.insert( std::pair<int,std::string>(3, "David") );

    //Iterate & print
    std::map<int,std::string,comp_asc>::iterator a_it; 
    for(a_it=int_map_asc.begin(); a_it!=int_map_asc.end(); a_it++)
           std::cout << "[" << a_it->first << "," << a_it->second << "]\n"; 



    std::cout << "\nint_map_desc: [key,value]\n"; 

    //Map declaration via function pointer as compare
    bool(*fn_compare_desc)(int,int) = compare_descend; //Create function ptr to compare_descend()
    std::map<int,std::string,bool(*)(int,int)> int_map_desc(fn_compare_desc); //fn ptr passed to constructor

    //Insert pairs into the map
    int_map_desc.insert( std::pair<int,std::string>(0, "Alan") );
    int_map_desc.insert( std::pair<int,std::string>(1, "Baye") );
    int_map_desc.insert( std::pair<int,std::string>(2, "Carl") );
    int_map_desc.insert( std::pair<int,std::string>(3, "David") );

    //Ititerate & print
    std::map<int,std::string,bool(*)(int,int)>::iterator d_it; 
    for(d_it=int_map_desc.begin(); d_it!=int_map_desc.end(); d_it++)
        std::cout << "[" << d_it->first << "," << d_it->second << "]\n"; 

    return 0; 
}

输出:

int_map_asc: [key,value]
[0,Alan]
[1,Baye]
[2,Carl]
[3,David]

int_map_desc: [key,value]
[3,David]
[2,Carl]
[1,Baye]
[0,Alan]

其他示例here