欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二分查找的几种不同的实现

程序员文章站 2024-03-20 09:58:52
...

不多说,直接上代码,注释解释清楚了

# include <iostream>
# include <vector>
# include <cstring>
# include <string>
# include <sstream>
# include <istream>

using namespace std;

////////////////////////////////////////////////////////////////////
template <typename T>
vector <T> scanf_r() {
    cin.sync();
    string input_string;
    while(true) {
        getline(cin, input_string);
        if (input_string != "\n") break;
    }
    istringstream input_stream(input_string);
    vector <T> ret;
    T item;
    while(input_stream >> item) ret.push_back(item);
    return ret;
}

template <typename T>
T scanf(string prompt="", istream & input_stream = cin){
    T ret;
    while (cout << prompt, !(input_stream >> ret)) {
        input_stream.clear();  // reset the state of cin
        input_stream.sync(); // synchronize the buffer of cin
    }
    return ret;
}
//////////////////////////////////////////////////////////////////////

/**
 * 最小的i, 满足arr[i] = target. 不存在 返回 -1
 */
int bin_1(vector<int> & arr, int target) {
    int size = arr.size();
    int l = 0, r = size - 1, mid;
    while(l < r) {
        mid = l + ((r - l) >> 1); // 奇数: 中间; 偶数: 两个中间数的第一个
        if(arr[mid] < target)
            l = mid + 1;
        else // arr[i] >= target
            r = mid;
    }
    return (arr[l] == target) ? l : -1;
}


/**
 * 最大i, 满足arr[i] = target。 不存在, 返回-1
 */
int bin_2(vector<int> & arr, int target) {
    int size = arr.size();
    int l = 0, r = size - 1, mid;
    while(l < r) {
        mid = l + ((r - l + 1) >> 1); // 奇数: 中间;  偶数 : 两个中间数的第二个
        if(arr[mid] > target)
            r = mid - 1;
        else // arr[i] <= target
            l = mid;
    }
    return (arr[l] == target) ? l : -1;
}


/**
 * 求最小的i,使得a[i] > target,若不存在,则返回-1
 */
int bin_3(vector<int> & arr, int target) {
    int size = arr.size();
    int l = 0, r = size - 1, mid;

    while(l < r) {
        mid = l + ((r - l) >> 1); 
        if(arr[mid] > target)
            r = mid;
        else
            l = mid + 1;
    }
    return (arr[l] > target) ? l : -1;
}


/**
 * 求最大的i,满足a[i] < target, 若不存在, 返回 -1
 */
int bin_4(vector<int> & arr, int target) {
    int size = arr.size();
    int l =0, r = size - 1, mid;
    while(l < r) {
        mid = l + ((r - l + 1) >> 1);
        if(arr[mid] < target)
            l = mid;
        else
            r = mid - 1;
    }
    return (arr[l] < target) ? l : -1;
}


/**
 * 求最小的i,满足a[i] >= target, 若不存在, 返回 -1
 */
int bin_5(vector<int> & arr, int target) {
    int size = arr.size();
    int l = 0, r = size - 1, mid;
    while(l < r) {
        mid = l + ((r - l) >> 1);
        if(arr[mid] >= target)
            r = mid;
        else
            l = mid + 1;
    }
    return (arr[l] >= target) ? l : -1;
}


/**
 * 求最大的i,满足a[i] <= target, 若不存在, 返回 -1
 */
int bin_6(vector<int> & arr, int target) {
    int size = arr.size();
    int l = 0, r = size - 1, mid;
    while(l < r) {
        mid = l + ((r - l + 1) >> 1);
        if(arr[mid] <= target)
            l = mid;
        else
            r = mid - 1;
    }
    return (arr[l] <= target) ? l : -1;
}


/////////////////////////////////////////////////////////////////////////////

void test( int (*bin) ( vector<int> &, int), string title) {
    cout << "------test " << title << " with target : 2 ----------" << endl;
    for(int i = 0; i < 3; i++) {
        vector<int> vec = scanf_r<int>();
        cout << bin(vec, 2) << endl;
    }
    cout << "------- end ---------------" << endl;
}



////////////////////////////////////////////////////////////////////////////

int main() {
    bool is_on = true;
    while(is_on) {
        cout << "choose a bin function to test: ";
        int key = scanf<int>();
        switch(key) {
            case 1:
                test(bin_1, string("bin_1(min i  for arr[i] = target)"));
                break;
            case 2:
                test(bin_2, string("bin_2(max i for arr[i] = target)"));
                break;
            case 3:
                test(bin_3, string("bin_3(min i for arr[i] > target)"));
                break;
            case 4:
                test(bin_4, string("bin_4(max i for arr[i] < target)"));
                break;
            case 5:
                test(bin_5, string("bin_5(min i for arr[i] >= target)"));
                break;
            case 6:
                test(bin_6, string("bin_6(max i for arr[i] <= target)"));
                break;
            case 0:
                is_on = false;
                break;
            default:;
        }

    }
    return 0;
}