我面临着持有大量字符串(~50k)的问题。每个字符串描述已经考虑过的场景。因此,当出现新方案时,如果其描述已在列表中,则将其丢弃。
我认为显而易见的选择是使用priority_queue字符串来执行binary_search。 (对数插入,对数查找)。
右?
好吧,我找不到使用标准C ++库的方法。 具体来说,priority_queue似乎没有.begin()。end() 方法给予binary_search()函数。
我不能使用标准库priority_queue + binary_search吗? 那么,还有什么用呢?
谢谢!
编辑1。 最后经过几次测试,我可以确认这个问题的最佳选择(优于其他问题)是使用set及其find方法。这是:
set<string> consideredOptions;
...
string newDescription = ....;
if ( consideredOptions.find(newDescription) == consideredOptions.end() ) {
consideredOptions.insert(newDescription);
}
编辑2。 priority_queue有一个名为 c 的受保护成员,它代表项目列表。然后,使用 .begin()和 .end()的方法很容易派生出一个新类。
class MyQueue : public std::priority_queue<std::string> {
public:
bool contains (const std::string & what) const {
return std::find (c.begin(), c.end(), what) != c.end();
}
};
答案 0 :(得分:1)
好吧,我找不到使用标准C ++库的方法。
您不需要队列,只需要一个可以高效插入和执行查找的集合。使用std::unordered_set
。它具有恒定时间插入和查找。
当您希望在到达队列的“前端”时处理事物(通常从队列中删除它们)时使用队列。根据你所描述的,你不需要那样做。你只关心事物是否在集合中,你不关心他们是否在前面。
使用std::set
或std::unordered_set
您甚至不需要费心去查找,只需尝试插入每个字符串即可。如果它已经在容器中,则返回值将告诉您插入失败。如果它不在容器中,则返回值告诉您它不在那里,但是在相同的操作中添加它,这是执行查找然后插入的两倍。
unordered_set<string> consideredOptions;
...
string newDescription = ....;
if ( consideredOptions.insert(newDescription).second ) {
// newDescription was not in the set (but is now)
}
else {
// newDescription was already considered
}