您的位置:首页 > 其它

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

2017-09-11 21:10 211 查看
不多说,直接上代码,注释解释清楚了

# 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: