在两个容器 C++ 中搜索匹配项

Posted

技术标签:

【中文标题】在两个容器 C++ 中搜索匹配项【英文标题】:search match items in two containers C++ 【发布时间】:2013-11-06 12:19:38 【问题描述】:

我有一个关于如何有效地搜索两个容器以找到相同项目的问题。

例如,我有two list A, B,我想找出列表 B 中与列表 A 匹配的所有项目。

在这种情况下,我需要有两个循环,一个在另一个里面。不好,因为对于A的每一项,我都在B里做一个整体的搜索。

你有一些想法或标准库(升压是可以的)来解决它;)?

非常感谢!

【问题讨论】:

“列表”是什么意思,一个数组? 相关/可能重复 - Check if two arrays are similar. 【参考方案1】:

您可以std::sort() 容器然后使用std::set_intersection()(我不完全确定该算法的名称)。复杂度将是O(n ln n + m ln m) 而不是O(n * m),其中nm 是序列的大小。

【讨论】:

std::set_itersection 是正确的。提到的复杂性是针对这两种排序的——如果序列已经排序,那么set_intersectionO(n+m) 如果我的计算是正确的,只排序一个容器并使用std::binary_search会更好,复杂度为O((n+m) ln m)。看我的回答。 @Arbe Mertz:根据容器的相对大小,它可能会更好:复杂性是 O((m + n) ln x) wit x max(m, n) 用于对两个容器进行排序,min(m, n) 用于仅排序一。如果mn 的大小大致相同,那没关系,如果它们显着不同(数量级),那么只排序一个会更好。下一个问题是,对于实际问题大小,哪个常数较小。 好吧,我想它只是归结为性能方面的常见问题:分析它;-)【参考方案2】:

正如您从不同的答案中看到的那样,有多种方法。这些中的任何一个都可能是正确的,具体取决于您的容器是什么以及范围是否已排序、范围的典型大小以及是否可以选择对范围进行排序。

如果两个容器都排序,std::set_intersection 是最好的方法,它的复杂性是O(n+m) 在比较和交换方面,对大小为 n 的容器进行排序具有复杂性O(n log(n))。对列表进行排序意味着交换列表节点,这很便宜。对向量进行排序实际上意味着交换元素,而成本取决于元素类型。 对于一个已排序容器和一个未排序容器,最好为已排序范围内未排序范围的每个元素执行std::binary_search。其复杂性将是O(n log(m)),其中n 是未排序的大小,m 是排序范围的大小。先对未排序的范围进行排序,然后再使用set_intersection,其复杂度将达到O(n log(n) + m),这更糟。 有两个未排序的容器,将其中一个排序,然后将binary_search 应用于另一个容器的元素,给出O((m+n) log(m)) 的复杂性,因此如果两个容器具有相同的类型,则排序容器越小越好。

【讨论】:

【参考方案3】:

如果您有两个列表 A(大小 n)和 B(大小 m),则使用嵌套循环查找 B 中存在于 A 中的每个元素是 O(nm)。

我建议使用 散列集。如果您使用 B 中的元素构建一个哈希集,您将花费 O(m) 构建该集合,然后 O(n) 在 hash_set(B) 中查找 A 的每个元素。所以复杂度是 O(n+m)

【讨论】:

【参考方案4】:

也许您可以先对数组中的 A 和 B 进行排序。然后计算相同的元素。它是 O(n*log(n)),但需要更多空间。

【讨论】:

【参考方案5】:

如果您希望优化解决方案,您应该分享有关问题域的更多信息。例如,如果您知道列表中的所有项目都是 1 到 100 之间的整数,您可以使用简单的布尔数组 [100],并通过在 A 上运行一次(引发适当的标志)然后再运行一次来​​完成任务在 B 上(测试标志)。

如果列表具有任意内容,您必须满足于通用解决方案。天真的解决方案是像你建议的那样有一个双循环,这并不一定那么糟糕。您可以进行一些实用的优化:

    应该在较短的列表上完成外循环(前提是您知道它们的长度)。这意味着您的内部循环可能会在您找到您的项目后立即中断(如果您找到它...)。 如果内存不是问题,您可以对两个列表进行排序,然后并行处理这两个列表,只要另一个列表的项目更大,就在一个列表上前进(就像您在它们之间进行排序合并一样) .这有一个数量级的 O(NlogN+MlogM+max(N,M)),这可能比 O(N*M) 更好,但在内存方面也很浪费。

【讨论】:

以上是关于在两个容器 C++ 中搜索匹配项的主要内容,如果未能解决你的问题,请参考以下文章

如何编写从两个搜索值返回匹配项的 sql 查询

Xapian - 除非向每个单词添加“”,否则搜索查询不会检索任何匹配项

在 Solr 中搜索日期范围或空/无字段 [重复]

如何从用户文本输入中搜索数据库记录以查找匹配项并避免提取信息? (PHP)

Jquery实现类似百度的搜索框

javascript 在对象数组中查找搜索项的匹配项