【问题标题】:How can I use Binary search to print all the duplicates strings in a sorted array?如何使用二进制搜索打印排序数组中的所有重复字符串?
【发布时间】:2020-11-13 06:14:40
【问题描述】:

仅使用二分搜索,如何获得具有重复项的请求元素,因为重复项将一个接一个,搜索条件应该是什么?

假设这是给定的数组,由用户输入,我们必须搜索“efg”是否存在,我们不知道索引,也不知道它重复了多少次,但如果存在,打印其重复次数。

array[][10]={"abc","efg","efg","jkl","jkl","jhk"}

【问题讨论】:

  • 如果你有二分搜索的位置,查看它之前和之后的索引,看看它们是否也相等。
  • 如果重复项彼此相邻,您可以遍历数组并打印它们。
  • @ChrisMM 是的,但是就像我们需要搜索元素本身一样,但我们也不知道它重复了多少次。
  • 先看看……这相等吗?不——继续。是的 - 在那个之前看看。重复。
  • 有一个标准算法:std::equal_range

标签: c++ c algorithm search binary-search


【解决方案1】:

如何使用二分搜索打印排序数组中的所有重复字符串?

寻找范围的简单但可能不是最优的算法:

首先使用二分查找查找第一个匹配项。这种二分搜索的变体称为“下界”。

然后,使用二分搜索查找最后一次出现。这种二分搜索的变体称为“上限”。在这里,我们可以通过限制搜索从找到的下限开始而不是从原始线性直到范围的开始来进行一些优化。


但是,您无需自己实现它,因为标准库已涵盖:std::equal_range


也就是说,如果您打算之后迭代元素,则无需搜索结尾,因为您会在迭代时遇到它。在这种情况下,只需找到 lower_bound 的开头,然后在执行所需操作(在您的示例中为“打印”)的同时线性迭代元素,直到找到不相等的元素。

【讨论】:

  • upper_bound 返回出现在您要查找的元素之后的第一个元素,以跟上 [first, last) 的 C++ 概念。
  • @lucieon 这正是人们在搜索范围末尾时想要找到的内容。
  • 我的评论是为了回应您的评论“然后,使用二进制搜索查找最后一次出现。这种二进制搜索的变体称为“上限”。”它不会找到最后一次出现但第一次出现的元素大于您找到的元素。
【解决方案2】:

您可以使用upper_bound 查找"efg" 之后大于它的第一个元素,使用lower_bound 查找"efg" 的第一个实例。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    vector<string> V{ "abc", "efg", "efg", "jkl", "jkl", "jhk" };
    cout << upper_bound(V.cbegin(), V.cend(), "efg") - lower_bound(V.cbegin(), V.cend(), "efg") << endl;
}

编辑:为了改进它,您可以先使用lower_bound 来检查字符串是否存在于数组中。如果是,则使用upper_bound 计算编号。实例数。

【讨论】:

  • 这假定元素已排序。这是在哪里说明的?
  • 在标题中。
  • 正如用户eerorika 指出的那样,有一个更好的功能可以完全满足要求,std::equal_range。应该比调用这两个函数要快。
  • auto p = std::equal_range(V.cbegin(), V.cend(), "efg"); std::cout &lt;&lt; std::distance(p.first, p.second);
  • @ChrisMM 如果数组中不存在该字符串,那么这将使工作加倍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 2020-06-26
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多