1. 程式人生 > 其它 >對於兩個二分模板的一些實驗測試

對於兩個二分模板的一些實驗測試

一、總結

1、模板1適合 查詢等於大於目標值的正數第一個值

2、模板2適合 查詢等於小於目標值的倒數第一個值

二、模板1測試(查詢等於大於目標值的第一個值)

#include <bits/stdc++.h>

using namespace std;
int l, r, k;

//排好序的陣列
int a[] = {1, 2, 3, 4, 6, 6, 6, 7, 8, 9, 10};

//符合的性質
bool check(int mid) {
    return k <= a[mid];//當前選中的mid,它所在位置的數值:a[mid]如果還是大於k的話,那麼需要向左移動
}

int main() {
    cout << "==============================================" << endl;
    //測試1:如果在陣列中查詢一個肯定存在的數字,比如6這個數,可以找到左側第一個6的位置
    l = 0, r = 10, k = 6;
    //模板1: 查詢等於大於目標值的第一個值
    while (l < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) r = mid;  // 這裡是r=mid, 說明check(mid)返回了true,就是目標值在[l,mid]這個範圍內。
        else l = mid + 1;         // [l,mid]這個範圍都不是合法範圍,所以下一次查詢直接從 l = mid + 1開始了
        //最後的l,r是答案 因為 l == r ,最終就是答案。
    }
    cout << l << " " << r << " " << endl;

    cout << "==============================================" << endl;
    //測試2:找出陣列中一個不存在的數字5,看看會發生什麼
    l = 0, r = 10, k = 5;
    //模板1: 查詢等於大於目標值的第一個值
    while (l < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) r = mid;  // 這裡是r=mid, 說明check(mid)返回了true,就是目標值在[l,mid]這個範圍內。
        else l = mid + 1;         // [l,mid]這個範圍都不是合法範圍,所以下一次查詢直接從 l = mid + 1開始了
        //最後的l,r是答案 因為 l == r ,最終就是答案。
    }
    cout << l << " " << r << " " << endl;
    //找不存在的數字5,它就會多走一個,最終定位在4這個數字上~
    return 0;
}

三、模板2測試(查詢等於小於目標值的倒數第一個值)

#include <bits/stdc++.h>

using namespace std;
int l, r, k;

//排好序的陣列
int a[] = {1, 2, 3, 4, 6, 6, 6, 7, 8, 9, 10};

//符合的性質
bool check(int mid) {
    return k >= a[mid];//當前選中的mid,它所在位置的數值:a[mid]如果還是小於k的話,那麼需要向右移動
}

int main() {
    cout << "==============================================" << endl;
    //測試1:如果在陣列中查詢一個肯定存在的數字,比如6這個數,可以找到右側第一個6的位置
    l = 0, r = 10, k = 6;
    //模板2: 查詢等於小於目標值的倒數第一個值
    while (l < r) {
        int mid = (l + r + 1) / 2;         // 這裡要 l + r +1 要不然會死迴圈
        if (check(mid)) l = mid;          // mid這個位置 滿足條件之後 查詢 [mid , right]的位置, 所以l移到mid的位置
        else r = mid - 1;                 // [mid,r] 不滿足條件, 所以要移到滿足條件的一方, r = mid - 1
    }
    cout << l << " " << r << " " << endl;

    cout << "==============================================" << endl;
    //測試2:找出陣列中一個不存在的數字5,看看會發生什麼
    l = 0, r = 10, k = 5;
    //模板2: 查詢等於小於目標值的倒數第一個值
    while (l < r) {
        int mid = (l + r + 1) / 2;         // 這裡要 l + r +1 要不然會死迴圈
        if (check(mid)) l = mid;           // mid這個位置 滿足條件之後 查詢 [mid , right]的位置, 所以l移到mid的位置
        else r = mid - 1;                  // [mid,r] 不滿足條件, 所以要移到滿足條件的一方, r = mid - 1
    }
    cout << l << " " << r << " " << endl;
    //找不存在的數字5,它就會多走一個,最終定位在4這個數字上~
    return 0;
}