1. 程式人生 > 實用技巧 >對使用者上傳檔案型別限制的工具類

對使用者上傳檔案型別限制的工具類

有人說,90%的程式設計師都手寫不出正確的二分查詢

沒錯,我就是那90%

c++的標準庫裡只提供了binary_search(),lower_bound(),upper_bound()三個函式,缺點就是,只能在陣列或者vector這樣的線性資料結構上二分

所以就需要整理一下二分的用法和程式碼

1,binary_search(arr[],arr[]+size,key,cmp)

功能:找到正好等於key的元素,成功則返回位置,否則返回陣列末尾指標

注意,給出的最後一個引數是比較函式的指標,如果不給出,預設呼叫標準庫中的less()函式,其實就是小於號。

這個是最好寫的,不需要考慮左右邊界或者失配的問題

(偽)程式碼:

int binary_search(arr[],arr[]+size,key,cmp) {
    int left = 0; 
    int right = nums.length - 1;
    while(left <= right) {
        int mid = (right + left) / 2;
        if(equal(arr[mid],key))
            return arr[]+mid; 
        else if (less(nums[mid],target))
            left = mid + 1
; else right = mid - 1; } return arr[]+size; }

2,lower_bound(arr[],arr[]+size,key,cmp)

這個函式的功能是找出第一個大於等於key的值,可以簡記為左邊界,和上一個函式不同的是,除非key值大於全部陣列中的值,才會返回arr[]+size,否則一定會返回一個有效值。

(偽)程式碼:

int lower_bound(arr[],arr[]+size,key,cmp){
    int left = 0;
    int right = size-1
; while (left <= right) { int mid = (left + right) / 2; if(less(arr[mid],key)){ left = mid + 1; } else{ right = mid - 1; } } return arr[]+left; }

注意,這個函式就比上一個難寫很多,比如left,right為什麼要小於等於,最後要返回的是left還是right,等等

3,upper_bound(arr[],arr[]+size,key,cmp)

這個函式的功能是找出大於key的第一個值的位置,簡稱右邊界

int upper_bound(arr[],arr[]+size,key,cmp){
    int left = 0;
    int right = size-1;
    //查詢第一個大於key的元素 
    while (left <= right) {
        int mid = (left + right) / 2;
        if (less(key,a[mid])) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return arr[]+left;
}

這個函式常用於給整數開平方根,因為大於key的第一個值,減去1,就是小於等於key的最後一個值

涉及到給整數開平方根或者類似的操作的,一定記得用二分,不要自作聰明求解析解,然後轉換成double,在cmath庫裡的函式求解,再轉換回來,絕對不要!

我是不會告訴你我被昨晚的atcoder arc的B題卡了一個多小時的,天知道,1e18的資料範圍,他是怎麼想到構造出卡掉double+sqrt的資料的

參考資料:

https://www.cnblogs.com/kyoner/p/11080078.html