自定义二进制搜索向量中

时间:2015-03-09 09:31:13

标签: c++ search vector binary-search

假设我有vector<int> myVec。让其中有n个元素。我知道这些元素按排序顺序(升序)并且它们是唯一的。让n = 10myVec为{2,4,6,8,10,12,14,16,18,20}。我给了lr 0<=l<=r<=n-1。现在,我想在子向量中搜索由边界vall定义的元素r,以便

  1. 如果找到val,则返回val
  2. 如果找不到val,则返回(如果可能)子向量中的值,该值小于val
  3. 如果上述任何一种情况不可能,则返回false(或者可能为-1)。
  4. 在上述情况下,如果l = 3r = 5。子向量是{8,10,12}。如果val = 8返回8.如果val = 7返回false(或-1)。如果val = 9返回8。

    我如何实现这一点。 我希望订单与二进制搜索相媲美。此外,是否可以使用std::binary_search()头文件下的algorithm

3 个答案:

答案 0 :(得分:0)

使用传统的二进制搜索并进行微小修改:

#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

答案 1 :(得分:0)

这样的事情?

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 :(得分:0)

这应该适合您,并且具有可扩展性和灵活性:

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);
}