Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中实现快速map+;_C++_Map - Fatal编程技术网

C++ 在C+中实现快速map+;

C++ 在C+中实现快速map+;,c++,map,C++,Map,我现在有了一个工作实现,可以映射范围的键,如下所示: class Range { public: Range(int from, int to = -1) : _from(from), _to( to >= 0 ? to : from) {} bool operator < (const Range& item) { return _to < item._from; } bool operator == (const Ra

我现在有了一个工作实现,可以映射范围的键,如下所示:

class Range {
public:
    Range(int from, int to = -1) : _from(from), _to( to >= 0 ? to : from) {}
    bool operator < (const Range& item) {
        return _to < item._from;
    }
    bool operator == (const Range& item) {
        return item._from >= _from && item._to <= _to;
    }
private:
    int _from, _to;
};

typedef std::map<Range, MappedType> my_map_type;
但是我需要比std::map更快的map实现。插入速度可以慢一些,但查找速度必须非常快。尝试了boost::unordered_map,但我无法让它与Range类一起工作(尽管我已经为Range对象实现了boost::hash_value)。find不返回任何内容(并且在find过程中,操作符==甚至没有被调用,我发现这很奇怪)


想法?

你不能用哈希表做这件事,你对
操作符==
的定义不能与哈希函数兼容:在你的代码
范围(10,20)==范围(15,-1)
中,哈希函数无法返回相同的哈希值

通常,哈希和相等必须兼容:
x==y
必须暗示
hash(x)==hash(y)
。当然,情况并非如此

因此,您需要一些基于比较的结构,比如基于树的
映射。您可以定义一个正确的等式比较器,并使用与您正试图执行的操作完全相同的
map::lower_bound
,而不是使用可能给您带来问题的坏的
运算符==

如果速度太慢,可以使用排序向量并使用
std::lower_bound
。搜索时间是O(logn),这与
std::map
近似相同,但实际上要快得多(没有指针跟踪,更好的局部性)。但是,它具有线性更新(插入/删除)时间

否则,您可能希望查看专门的结构,例如,但它们没有在STL中实现(可能是Boost?)


无论如何,隐式
Range(int)
构造函数具有误导性,并且可能有害。您应该将其声明为
explicit
,并使用
find(Range(40))
代替
find(40)

无论是使用
std::map
还是任何其他容器,您尝试执行的操作都将无效。您的
操作符正在使用std::map,它通常作为红黑树实现。multi_index container还提供了基于红黑树的容器,但是带有压缩节点(比指针小),因此由于工作集更小,它将比std::map更快


另一种选择是使用散列,这样在没有散列冲突的情况下,有些人的查找将是O(1)。

也许你的散列有问题
operator==
仅在找到具有正确哈希的项时调用。Hmm。。我想我知道为什么。由于无序_映射使用散列值,因此搜索键(与find一起使用)的散列值将仅匹配具有单数范围(即从==到)的条目。您的散列值实现将非常有用。另外,您是否尝试过使用排序向量进行二进制搜索,而不是使用地图?它们通常具有更快的搜索速度(但插入速度较慢)。谢谢矢量提示,听起来是个好主意。也许是boost token map?只是澄清一下:线性更新时间——而不是线性搜索时间+1@Giuseppe:间隔树不适用于不重叠的范围。@Matthieu:OP在哪里说他的间隔是不重叠的?无论如何,区间树支持区间查询中的点(我假设OP正在尝试这样做),范围是否重叠是无关的。你的意思是它们杀伤力太大了吗?@Giuseppe:是的,我的意思是,它们是非常复杂的野兽,只需要非常简单的需要。复杂度和性能通常不能同时进行,因此它不能解决OP问题。@Matthieu:你说得对,但我看不出问题中有任何东西暗示范围是不相交的。你怎么知道的?顺便说一句,如果它们是不相交的,那么在第一个端点上用一个简单的
map
和一个
lower\u-bound
就可以了。我使用的范围是不重叠的,所以m.find(N)一直有效(我已经进行了广泛的测试)好了,我做了一个键入的范围(它可以容纳我想要“map”的内容),并使用lower\u-bound和Pred on\u-to,然后检查值是否大于等于。这样我就可以找到正确的范围。希望快一点…:)隐马尔可夫模型。。。向量实现实际上比map实现慢。是多么令人失望。是的,但是考虑我做M.查找(30),然后我想以范围(10, 35)作为关键字返回条目,但是范围(30, 30)不会有与范围相同的哈希(10, 35)…
my_map_type m;
m[Range(0, 20)] = Item1;
m[Range(30,40)] = Item2;

my_map_type::iterator it = m.find(15);
assert(it->second == Item1);
it = m.find(40);
assert(it->second == Item2);
it = m_find(25);
assert(it == m.end());