问题
I'm a beginner C++ programmer so there are language constructs that I don't understand which prevents me from understanding map's API (for your reference, here)
More to the point, some questions:
How do I change the internal sorting scheme of map so that, given that we're working with map::<string, ...>
, the key values are sorted alphabetically?
More specifically about the map::key_comp
, is it a define-and-forget thing where once we define what it means for two elements of the same type to be "unequal (one is less than the other)", then the sorting is done internally and automatically - so all we need to is insert key/value pairs? Or do we have to define equality/ordering and then call the function explicitly to return a boolean to implement ordered insertion?
回答1:
Here's an example of how you give the sorted map a template argument to use a non-default sort:
std::map<int, int, std::greater<int> > m;
Taken from C++ std::map items in descending order of keys
Also, for a more complex example: how to declare custom sort function on std::map declaration?
回答2:
[Solved] Solution I'd chosen
Suppose your map was: map<int,vector<int>,compAB> myMap;
Then you need to do 2 things to define "compAB":
Define a comparison function that returns true or false/(or 1 or 0). I haven't tested whether this function can take multiple arguments (although I don't see why it can't so long as it returns a bool
. This function should specify how you intend to order two objects of the same type as the key
value in your your map.
bool compare(int a, int b)
{
if(a < b) return true;
return false; //Default
}
The API for the map::key_comp object (here indicates that the comparison function needs to return true if the first argument is "less than"/"comes before" the second argument. It should return false otherwise source). Here, I've used a simple criteria for determining "less than": a precedes b if a<b, as the computer evaluates it.
Create a struct whose member consist of just an operator-overload:
struct compAB
{
bool operator()(int i1, int i2){
return compare(i1, i2);
}
};
Then, you can make the declaration: map<int,vector<int>,compAB> myMap;
and any calls to insertion() will insert the pairs you've indicated according to the key-ordering scheme you specified
For instance:
#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;
}
Output:
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]
Additional examples here.
来源:https://stackoverflow.com/questions/35247239/how-do-i-change-the-map-containers-internal-sorting-scheme