#include <iostream>
#include <set>
#include <tuple>
struct Key {
int field1;
int field2;
Key(int field1, int field2) : field1(field1), field2(field2) {}
bool operator<(const Key& other) const {
// Is this acceptable?! Seems to work
if (field2 == 0 || other.field2 == 0) {
return field1 < other.field1;
} else {
return std::tie(field1, field2) < std::tie(other.field1, other.field2);
}
}
};
int main() {
std::set<Key> values{Key(4,3), Key(5,9), Key(5,7), Key(5,8), Key(6,1)};
std::cout << values.find(Key(5,0))->field2 << std::endl; // Prints '7'
auto range = values.equal_range(Key(5,0));
for (auto i = range.first; i != range.second; i++) {
std::cout << i->field2; // Prints '789'
}
return 0;
}
Field2在我的数据中并不总是可用,因此有时我使用通配符值0,它可以匹配field1匹配的任何值。如果我从不插入具有通配符值的元素,并且只在集合中查找它们,这在C ++中是否有效?我可以使用find函数返回在这种情况下的任何值,这在我的代码中很少发生,但希望它在重复调用时会是相同的值。
根据specification,似乎二进制搜索不需要严格的弱排序,这应该是执行查找时数据结构上使用的唯一算法,对吧?或者是否有一些我应该担心的未定义行为?
25.4排序和相关操作
...对于25.4.3中描述的算法以外的算法 正确地说,comp必须对值进行严格的弱排序......
25.4.3二进制搜索
答案 0 :(得分:1)
你错了。 std::set::find
在二叉搜索树中进行查找(在典型的实现中)。这可能看起来像二进制搜索算法,但25.4.3中的算法通常不用于查找。树只支持非随机访问迭代器,而使用线性迭代器的二进制搜索比使用数据在BST中的知识的查找要慢得多。
std::set
的比较器必须符合Compare概念,这需要strict weak ordering。
如果我从不插入具有通配符值的元素,并且只在集合中查找它们,这在C ++中是否有效?
技术上没有,因为你违反了要求。从包含{x, 0}
和{x, a}
的集合中查找{x, b}
时,至少会有不确定的结果。两者都可以找到。如果这不重要,那么我怀疑典型的实施会带来麻烦。你所做的并不能保证按标准工作,这足以让大多数人回避它。