C++ 如何找到对应于键向量的所有元素?

C++ 如何找到对应于键向量的所有元素?,c++,algorithm,c++11,dictionary,stl,C++,Algorithm,C++11,Dictionary,Stl,我有一个std::vector k带有我要查找的witch的键值。我有一个std::map表我在中搜索。我想得到一个std::vector v(如果表中存在此类值,则并非所有键都可以显示在表中,这一事实对我来说并不重要,而k中的键可能比中的键多得多这一事实很重要)。如何找到与键对应的所有值 使用table的table[k_元素]。为k中的每个元素查找(k_元素)似乎是一种非常糟糕的方法,我也不能这样做,因为我可以以小组的方式来做( 对k中的每个元素使用table[k_元素]或table.find

我有一个
std::vector k带有我要查找的witch的键值。我有一个
std::map表我在中搜索。我想得到一个
std::vector vk
中所有键的值的code>(如果
中存在此类值,则并非所有键都可以显示在
中,这一事实对我来说并不重要,而
k
中的键可能比
中的键多得多这一事实很重要)。如何找到与键对应的所有值

使用
table的
table[k_元素]
。为
k
中的每个元素查找(k_元素)
似乎是一种非常糟糕的方法,我也不能这样做,因为我可以以小组的方式来做(

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

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


使用lambdas、map等工具可以实现这一点,但这并不是“更好”或更快,只是可读性较差。

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

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

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

回答得很好。特别是,“虽然密钥可能比k中的密钥多得多”(我的黑体字)表示通过
table
k
中查找键的线性迭代比重复的O(log2N)探测更糟糕。可靠的替代方法是使用
std::unordered_map
而不是
std::map
。没有比线性更快的解决方案,但您引用的解决方案是
O(| k | logn)
。理论上,你可以在
O(|k |+n)
中进行排序,如果| k |足够大,这可能会更快。例如,如果
k
碰巧被排序,那么得到
O(| k |+n)
是一个非常简单的算法,如果你将键排列在一个无序的集合中,你可以实现
O(n)
时间,尽管
O(k*logn)考虑到
n>>k
@rabensky和Tony D是对的,会更快:有一些方法比我提出的方法更快。除非地图中的关键点数量相当大(10或100的数千个),否则它们不太可能重要。如果这确实重要,您还可以将std::map更改为std::hash_map,这样您就可以得到线性时间解决方案。