【问题标题】:Time Complexity of std::multimap::equal_rangestd::multimap::equal_range 的时间复杂度
【发布时间】:2011-05-12 18:23:38
【问题描述】:

下午好,我想知道std::multimap::equal_range 的时间复杂度是多少?是 Big-O(n) 还是 BIG-0(log n)。我记得读过std::multimap::erase 的时间复杂度“是对数加上被删除序列长度的线性时间。” http://frank.mtsu.edu/~csjudy/STL/Multimap.html>

【问题讨论】:

    标签: c++ stl complexity-theory


    【解决方案1】:

    C++03 标准,23.1.2 中的表 69(“关联容器要求”)表明 equal_range 具有对数复杂度。

    【讨论】:

    • 史蒂夫·杰索普,谢谢您的回答。我刚刚接受了你的回答,我们正在使用一个以 char * 指针为键的多映射容器,我们发现只要 char * 指针不是坏指针(Windows 术语),equal_range 就正确。在 Linux 中,他们将错误指针称为“地址超出范围”。我们对 equal_range 对良好 char * 指针的要求的观察是否正确。我们选择不将 std::string 作为多映射键,因为与好的指针比较器仿函数 bool(char *left, char *right) 相比,strcmp 非常昂贵。谢谢。
    • 就标准而言,是的,映射中的键必须保持有效值,并且任何指向已释放数据的指针或错误地址的使用,即使只是将其作为指针值进行比较如果不取消引用它,在技术上是无效的。在实践中,我有点惊讶它实际上失败了 - 你确定你的代码从未取消引用指针吗?
    • Steve Jessop,谢谢您的回复,如果我们的代码实际上推迟了一个错误的指针,那么说会发生访问冲突(Windows)或总线错误/分段错误是否正确在(Linux)上?这是一段代码摘录: 1.UnmapViewOfFile(PrevMapPtr); 2. TmpPrevMapPtr = PrevMapPtr; 3. typedef std::multimap::const_iterator I; std::pair b = mmultimap.equal_range(TmpPrevMapPtr); 4. for (I i=b.first; i != b.second; ++i){ range_type.erase(i->second);感谢您的帮助。
    • Steve Jessop,谢谢您的回复,如果我们的代码实际上推迟了一个错误的指针,那么说会发生访问冲突(Windows)或总线错误/分段错误是否正确在(Linux)上?这是一段代码摘录: 1.UnmapViewOfFile(PrevMapPtr); 2. TmpPrevMapPtr = PrevMapPtr; 3. typedef std::multimap::const_iterator I; 4. std::pair b = mmultimap.equal_range(TmpPrevMapPtr); 5. for (I i=b.first; i != b.second; ++i){ range_type.erase(i->second); 6. 擦除计数 = mmultimap.erase(TmpPrevMapPtr);感谢您的帮助。
    • Steve Jessop,对于发布我的评论的两个版本,我深表歉意。如果您有时间,请查看此评论之前的评论。感谢您的帮助。
    【解决方案2】:

    equal_range 是一个 O(log n) 运算,返回 lower_boundupper_bound 对。

    这意味着它将返回一个迭代器范围,从大于或等于搜索键的第一个键开始,以大于搜索键的第一个键结束。

    【讨论】:

    • @Cory Nelson,谢谢您的回答。我刚刚接受了你的回答。 std::multimap::equal_range 会与 char* 指针的搜索键一起使用吗?我必须找到一个好的函数来散列指针值吗?谢谢。
    • equal_range 适用于任何类型。它使用您在multimap 构造函数中提供的比较器——如果char* 的默认比较器(less<T>)不能满足您的需求,您需要自己定义。无论哪种方式,它都不需要做任何散列。
    • @Cory Nelson,我使用调试器逐步完成了 multimap::equal_range 函数,我发现 char* 的默认一个 less 比较指针地址,Left_
    • 比较器是一个带有签名bool(T a, T b)的函数类型,如果ab之前,则返回true。它可以是函数指针或仿函数。
    • @Frank,我提供了一个适当的比较函数来回答your other question
    【解决方案3】:

    我从未真正找到比SGI STL Programmer's Guide 更好的此类信息来源。在这种情况下,您感兴趣的页面是排序关联容器concept page,它在复杂性保证部分下声明:

    下限、上限和相等范围都是对数的。 [1]

    ...

    [1] 这比Associative Container 提供的保证要强得多。 Associative Container 中的保证仅适用于平均复杂度;最坏情况的复杂性被允许更大。然而,Sorted Associative Container 提供了最坏情况复杂度的上限。

    【讨论】:

    • @olivier Seiler,谢谢您的回答。我刚刚接受了你的回答。谢谢。
    • 嗯,标准更权威,但SGI docs更方便。有时你会被那里和 C++ 标准之间的一些变化所吸引。
    • @Steve Jessop,如果您知道 SGI 和标准之间的任何具体变化,您能回答 stackoverflow.com/questions/5266386/… 吗?谢谢。
    • @Mark:我已经给它加了星标,我会尽量记住,但说实话,自从我安装了 Foxit,它可以在比 Adob​​e Reader 的地质时间更短的时间内搜索 PDF,我不再经常使用 SGI 文档了 :-)
    猜你喜欢
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    相关资源
    最近更新 更多