【问题标题】:Binary Search with Duplicates具有重复项的二进制搜索
【发布时间】:2022-01-02 21:47:03
【问题描述】:

我正在做这个特殊的练习,我必须实现二进制搜索算法,该算法返回排序数组中第一次出现的元素的索引,如果它包含重复项。由于我主要在 C++ 中研究我的算法技能,因此我只尝试在 C++ 中进行。这是我的代码:

#include <iostream>
#include <cassert>
#include <vector>

using std::vector;

int binary_search(const vector<int> &a, int x, int n) {
  int left = 0, right = n-1; 

  while(left<= right){
    int mid = left + (right-left)/2;
    if(x== a[mid]){
      return mid;
    }else if(a[mid]>x){
      right = mid-1;
    }else{
      left = mid+1;
    }
  }
      return -1;
}


int first_occurence(const vector<int>&a, int x, int n) {
  int out = binary_search(a, x, n);
  if(out !=-1){
     for(int i = out;i>0&& a[i]==x;--i ){
        out = i;
     }
  }
  return out;
}

int main() {
  int n;
  std::cin >> n;
  vector<int> a(n);
  for (size_t i = 0; i < a.size(); i++) {
    std::cin >> a[i];
  }
  int m;
  std::cin >> m;
  vector<int> b(m);
  for (int i = 0; i < m; ++i) {
    std::cin >> b[i];
  }
  for (int i = 0; i < m; ++i) {
    std::cout << first_occurence(a, b[i], n) << ' ';
  }
}

程序的第一个输入告诉数组应该包含多少项,第二个是这些元素的枚举,第三行告诉要搜索多少个键,最后一行是各个键。输出是键的索引,如果没有找到这样的键,则输出 -1。

我的策略是使用函数来查找键的索引。如果找到,则在重复的情况下,第一次出现的索引必须较低。这就是first_occurence() 方法的作用;继续循环直到找到第一次出现。

对于以下输入:

10
1 5 4 4 7 7 7 3 2 2
5
4 7 2 0 6

输出是:

-1 4 -1 -1 -1

这仅对密钥 7 正确。我已经尝试调试了很长时间,但我无法找出问题所在。

【问题讨论】:

    标签: c++ search binary-search


    【解决方案1】:

    返回一个元素在排序数组中第一次出现的索引,

    您的二分搜索算法要求在调用数据之前对数据进行排序

    例子:

    #include <algorithm>
    #include <sstream>
    
    int main() {
        std::istringstream in(R"aw(10
    1 5 4 4 7 7 7 3 2 2
    5
    4 7 2 0 6
    )aw");
    
        int n;
        in >> n;
        vector<int> a(n);
        for (auto& v : a) {
            in >> v;
        }
    
        std::sort(a.begin(), a.end());               // <- add this
    
        // display the sorted result:
        for (auto v : a) std::cout << v << ' ';
        std::cout << '\n';
    
        int m;
        in >> m;
        vector<int> b(m);
        for (auto& v : b) {
            in >> v;
        }
        for (auto v : b) {
            std::cout << v << ' ' << first_occurence(a, v, n) << '\n';
        }
    }
    

    【讨论】:

    • 现在我看到了,很明显对元素进行了排序,但我没有处理。谢谢你:)
    • @yousafe007 很高兴它有帮助。不客气!
    猜你喜欢
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    • 2019-05-02
    相关资源
    最近更新 更多