Ale*_*lex 2 c++ dictionary stdmap c++11 ranged-loops
假设我有以下简单程序(http://cpp.sh/5sygh):
#include <map>
#include <iostream>
using Key = std::pair<unsigned long, unsigned long long>;
struct KeyLess {
bool operator()(const Key& lhs, const Key& rhs) {
if (lhs.first < rhs.first) {
return true;
}
if (lhs.second < rhs.second) {
return true;
}
return false;
}
};
int main() {
std::map< Key , int, KeyLess> m;
m[Key{2, 169}] = 1;
m[Key{1, 255}] = 2;
m[Key{1, 391}] = 3;
m[Key{1, 475}] = 4;
std::cout << "Elements in map: " << m.size() << std::endl;
for(const auto &x: m) {
std::cout <<"Value: "<< x.second << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
输出只包含 2 个项目,而不是地图中的 4 个:
Elements in map: 4
Value: 2
Value: 1
Run Code Online (Sandbox Code Playgroud)
我在这里想念什么?
您的 less 运算符应该是:
struct KeyLess {
bool operator()(const Key& lhs, const Key& rhs) {
if (lhs.first < rhs.first) {
return true;
}
if (lhs.first == rhs.first && lhs.second < rhs.second) {
return true;
}
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
当您将结构与多个元素进行比较时,将结构视为单词而将元素视为字符可能会有所帮助。
通过此修改,less 运算符按字典顺序工作,即在对两个相同长度的单词进行排序时比较它们的方式:在下一个位置继续比较,而这些单词在当前位置具有相同的字符,并决定字符何时位于当前位置不同。如果您到达两个单词的末尾,则单词相等。
您的比较函数不符合严格弱排序的要求。
在 SWO 中,如果 A < B 且 B < C,则 A 必须小于 C。还通过查看两个值是否不小于彼此来检查密钥相等性。如果(!(a<b) && !(b<a))那么a == b。两个键不应都小于彼此。
对于您的密钥并使用您的比较功能
Key{2, 169} < Key{1, 255} // this is true because 169 < 255
Key{1, 255} < Key{2, 169} // this is also true because 1 < 2
Run Code Online (Sandbox Code Playgroud)
显然这是一个问题,因为使用您的比较器,这两个键的比较都比彼此少。
我建议的解决方案:由于您的键是std::pairs,因此您不需要定义新的比较器。std::pair默认情况下已经使用字典比较。
您可以隐藏比较器的复杂性并通过使用std::tie.
bool operator()(const Key& lhs, const Key& rhs)
{
return std::tie(lhs.first, lhs.second) < std::tie(rhs.first, rhs.second);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
288 次 |
| 最近记录: |