【问题标题】:How to find all elements that correspond to a vector of keys?如何找到与键向量对应的所有元素?
【发布时间】:2015-06-02 01:50:28
【问题描述】:

我有一个std::vector<std::string> k;,其中包含我要寻找的女巫的键值。我有一个std::map<std::string, void*> table;,我在其中搜索。我想获取k 中所有键的值的std::vector<void*> v;(如果table 中存在此类值,则并非所有键都可以在table 中显示而这个事实对我来说并不重要,而可以有比k 更多的键这一事实很重要)。如何找到所有键对应的值?

k 中的每个元素使用table.find(k_element) 中的table[k_element] 似乎是一种非常糟糕的方法,我也不能find any algorithm in STL 可以以组的方式进行...(

【问题讨论】:

    标签: c++ algorithm c++11 dictionary stl


    【解决方案1】:

    对 k 中的每个元素使用 table[k_element] 或 table.find(k_element) 似乎是一种非常糟糕的方式

    我不知道为什么这感觉很糟糕。即使 STL 中有一个算法可以为您执行此操作,它也必须遍历 k 中的每个值——对于这个问题,没有比线性时间更快的解决方案。我想有时人们会认为一行代码总是比循环快,即使那一行代码调用了一个包含循环的函数。

    有一些方法可以通过 lambdas、map 等实现这一点,但这并不是“更好”或更快,只是可读性较差。

    【讨论】:

    • 好答案。特别是,“虽然可以有 比 k 中更多的键”(我的粗体)这一事实表明通过tablek 中寻找键的线性迭代会比重复的 O(log2N) 探测更糟糕。一个可靠的替代方法是使用std::unordered_map 而不是std::map
    • 没有比线性更快的解决方案,但您引用的解决方案是O(|k| log n)。从理论上讲,您可以在O(|k| + n) 中执行此操作,如果 |k| 会更快。足够大。例如,如果k恰好被排序,那么得到O(|k|+n)是一个非常简单的算法
    • 如果你将键排列在一个unordered_set中,你可以达到O(n)的时间,尽管O(k*log n)会更快,考虑到n>>k
    • @rabensky 和 ​​Tony D 是对的:有一些方法可以比我提出的更快。除非您的地图中的键数量非常大(10 或 100 的数千个),否则它们不太重要。如果这很重要,您也可以从 std::map 更改为 std::hash_map ,您将获得线性时间解决方案。
    【解决方案2】:

    您的问题有不同的解决方案,其中一些:

    • k中的所有键放入unordered_set中,遍历表并查找集合中的每个键,您将获得O(n)。您可以考虑将表更改为将元素存储在连续内存中的数据结构(可能是使用池分配器的映射或幕后带有std::vector 的数据结构),这样算法将更加缓存友好(因此,可能相当快),尽管插入此数据结构的时间会很慢。
    • 遍历k并查找表中的每个键,您将获得O(k*log(n)),如果您将表更改为unordered_map,您可以获得O(k)。虽然,您必须考虑到计算字符串的哈希可能非常慢,但有时比较字符串并有日志时间进行查找比计算键的哈希并有恒定的查找时间更好。选择取决于密钥的扩展和性质。
    • 您可以对k 中的元素进行排序并遍历有序集,每次查找后您将知道下一次查找的起点,因此每次查找都会比上一次查找更快。由于std::map 不允许您为搜索提供起点,您可以使用此功能实现自己的二叉搜索树。

    还有更多,最佳解决方案取决于数据集的大小、密钥的性质和其他因素。研究问题,选择一两个解决方案,实施、测试并在必要时进行迭代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2021-08-03
      相关资源
      最近更新 更多