容器std::map
总是根据键值对键进行排序。例如,是否可以对声明时设置的位数进行排序?
我有一个计数设置位的功能:
for(size_t i = 0; i < CHAR_BIT * sizeof value; ++i, value >>= 1) {
if ((value & 1) == byteState) ++num_bits;
}
但我在宣布地图时不知道如何应用它:
std::map<int, int> myMap = {
{1,2},
{3,4},
//...
}
我试图将它作为声明<int,int,decltype(countSetBits)>
中的第三个参数,但没有运气。
答案 0 :(得分:6)
您需要将函数包装在二元运算符中,如下所示:
#include <iostream>
#include <map>
#include <algorithm>
int cntBits(int value) {
int num_bits=0;
for(size_t i = 0; i < 32 ; ++i, value >>= 1) {
if ((value & 1) == 1) ++num_bits;
}
return num_bits;
}
struct cntBitsCmp {
bool operator()(int a, int b) {
return cntBits(a) < cntBits(b);
}
};
现在您可以在声明中使用cntBitsCmp
:
std::map<int,int,cntBitsCmp> myMap= {
{128,2},
{3,4},
...
};
这是demo on ideone。它正确地在3之前命令128,因为3设置了两个位,而128只有一个。
答案 1 :(得分:1)
基本上这可以按你的意愿运作:
bool comp(int x , int y ){
return __builtin_popcount(x) < __builtin_popcount(y);
}
int main(){
bool(*fn_pt)(int,int) = comp;
std::map<int, int, bool(*)(int,int) > myMap (fn_pt);
myMap[7]=11;
myMap[8]=12;
cout<<myMap.begin()->first<<endl; // you get 8 instead of 7
}
答案 2 :(得分:0)
自C++11起,您也可以使用lambda expression代替定义比较功能。如果将其与std::bitset::count结合使用而不是使用自己的计数功能,则代码将变得很短:
auto comp = [](int a, int b) { return std::bitset<32>(a).count() < std::bitset<32>(b).count(); };
std::map<int, int, decltype(comp)> m(comp);
注意:与dasblinkenlight的solution相似,为清楚起见,我假设使用32位整数。 请根据您的需要修改代码。