【问题标题】:Custom binary search in vector向量中的自定义二分搜索
【发布时间】:2015-03-09 20:54:27
【问题描述】:

假设我有一个vector<int> myVec。让其中有n 元素。我知道这些元素是按顺序排列的(升序),而且它们是独一无二的。设 n = 10myVec 为 {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}。我得到了lr 这样0<=l<=r<=n-1。现在我想在 subvector 中搜索一个元素 val,它由边界 lr 这样定义,

  1. 如果找到val,则返回val
  2. 如果找不到val,则返回(如果可能)子向量中的一个值,该值刚好小于val
  3. 如果以上任何一项都不可能,则返回 false(或可能是 -1)。

在上述情况下,如果l = 3r = 5。子向量是 {8, 10, 12}。如果val = 8 返回8。如果val = 7 返回false(或-1)。如果val = 9 返回8。

我该如何实现。 我想要类似于二分搜索的顺序。另外,是否可以使用algorithm 头文件下的std::binary_search()

【问题讨论】:

  • 如果你想进行二分搜索,一个名为binary_search 的算法听起来很有希望。你为什么不试试呢?
  • @ZanLynx 这不是简单的二进制搜索。还有其他条件。
  • 我看不出其他条件有何不同。请解释一下。
  • @ZanLynx 看看当 val = 9 时会发生什么。它返回子向量中小于 9 即 8 的元素。
  • 你绝对需要二分搜索吗?改用std::lower_bound 怎么样?

标签: c++ search vector binary-search


【解决方案1】:

这样的?

int search(int l, int r, int value) {
  if (l > vec.Size() || r > vec.Size() || l > r) return -1;
  for (int i = r; i >= l; --i) {
    int v = vector[i];
    if (v <= value) return v;
  }
  return -1;
}

还是需要二进制?

int BinarySearch(int l, int r, int value) {
  return PrivateBinarySearch(l, r, (l+r)/2, value);
}

int PrivateBinarySearch(int l, int r, int index, int value) {
  if (vector[index] == value) return value;
  else if (vector[index] > value) {
    if (index == l) return -1;
    else if (index == r) return -1;
    else return PrivateBinarySearch(l, index, (index-1+l)/2, value);
  }
  else { // vector[index] < value
    if (index == l) return vector[index];
    else if (index == r) return vector[index];
    else return PrivateBinarySearch(index, r, (index+1+r)/2, value);
  }

希望对你有帮助

【讨论】:

    【解决方案2】:

    这应该适合你,并且非常可扩展和灵活:

    template<typename T>
    typename vector<T>::const_iterator 
    find_or_under (typename vector<T>::const_iterator start, typename vector<T>::const_iterator end, 
                    const T& val)
    {
        auto el = std::lower_bound(start, end, val);
    
        //if not found, propagate
        if (el == end)
            return el;
    
        //if it's equal, just return the iterator
        if ((*el) == val)
            return el;
    
        //if there is no value of an equal or smaller size, return the end
        if (el == start)
            return end;
    
        //otherwise, return the previous element
        return el-1;
    }
    
    //Functor representing the search
    struct CustomSearch
    {
        //Create a searcher from a subrange
        CustomSearch (const vector<int> &v, size_t l, size_t r)
        {
            start = std::lower_bound(std::begin(v), std::end(v), l);
            end = find_or_under(start, std::end(v), r) + 1;
        }
    
        //Calling the searcher
        //Returns this->end on not found
        auto operator() (int val)
        {
            return find_or_under(start, end, val);
        }
    
        vector<int>::const_iterator start;
        vector<int>::const_iterator end;
    };
    
    int main() {
        vector<int> v =  {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
        CustomSearch searcher {v, 3, 8};
        cout << *searcher(6);
    }
    

    【讨论】:

      【解决方案3】:

      使用传统的二分查找,稍作修改:

      #include <iostream>
      #include <vector>
      
      
      int search(const std::vector<int> &vec, int l, int r, int val)
      {
              int pivot, xl = l, xr = r, mid;
      
              do {
                      /* Not exact match, check if the closest lower match is in the 
                       * subvector. */
                      if (xl > xr) {
                              return xr >= l ? vec[xr]: -1;
                      }
      
                      mid = (xl + xr) / 2;
                      pivot = vec[mid];
                      if (val < pivot) {
                              xr = mid - 1;
                      } else if (val > pivot) {
                              xl = mid + 1;
                      } else if (val == pivot) {
                              return val;
                      }
              } while (true);
      }
      
      int main()
      {
              std::vector<int> myVec(10);
              myVec[0] = 2;
              myVec[1] = 4;
              myVec[2] = 6;
              myVec[3] = 8;
              myVec[4] = 10;
              myVec[5] = 12;
              myVec[6] = 14;
              myVec[7] = 16;
              myVec[8] = 18;
              myVec[9] = 20;
      
              int l = 3, r = 5;
      
              std::cout << "search(3, 5, 8) = " << search(myVec, 3, 5, 8) << std::endl;
              std::cout << "search(3, 5, 7) = " << search(myVec, 3, 5, 7) << std::endl;
              std::cout << "search(3, 5, 9) = " << search(myVec, 3, 5, 9) << std::endl;
      
              return 0;
      }
      
          enter code here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-17
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        相关资源
        最近更新 更多