#include <cstdlib>
#include <iostream>
using namespace std;
typedef unsigned int u_int ;
template<typename T> class CBSearch
{
public:
static int find(const T& target, const T* array, u_int size)
{
u_int pos1=0, pos2=size-1;
while(pos2 >= pos1){
u_int i = (pos2 + pos1)/2;
if(i == pos1){
if(target == *(array+pos1))
return _shift(target, array, pos1);
else if(target == *(array+pos2))
return pos2;
else
return -1;
}
else{
if(target > *(array + i))
pos1 = i;
else if(*(array + i) > target)
pos2 = i;
else
return _shift(target, array, i);
}
}
return -1;
}
protected:
static inline u_int _shift(const T& target, const T* array, u_int pos)
{
while(pos > 0){
if(array[pos-1] == target) --pos;
else break;
}
return pos;
}
};
template<typename T>class CBSearchRecursion
{
public:
/*
好的实现基于清晰的构思,方便的调试,有效的验证
构思:( 写适用于各种情况的代码是神人.....可惜我不是......)
每次调用过程中逐渐缩小查找范围,当范围足够小就用最直观的实现方式
*/
static int find(const T& target, const T*array, u_int size)
{
if(size <= 0)
return -1;
int mid = (size - 1)/2;
if(array[mid] == target)
return _shift(target, array, mid);
else if(array[mid] > target)
return find(target, array, mid);
else{
if(mid == 0){ // size == 2 || size == 1
if(size == 1)
return array[mid] == target?mid:-1;
else{
if(array[mid] == target)
return mid;
else if(array[++mid] == target)
return mid;
else
return -1;
}
}
else{
int tmp = find(target, array+mid, size-mid);
tmp = tmp==-1?-1:mid + tmp ;
return _shift(target, array, tmp);
}
}
}
protected:
static u_int _shift(const T& target, const T* array, u_int pos)
{
while(pos > 0){
if(array[pos-1] == target) --pos;
else break;
}
return pos;
}
};
int main(int argc, char *argv[])
{
while(1){
u_int arr_size = 0;
cout << "input arr size:";
cin >> arr_size;
int* arr = new int[arr_size];
for(u_int i = 0; i < arr_size; ++i){
cin >> *(arr+i);
}
while(1){
int k = 0;
cout << "to find your num:(0 to break)";
cin >> k;
if(k ==0 ) break;
//int pos = CBSearch<int>::find(k, arr, arr_size);
int pos = CBSearchRecursion<int>::find(k, arr, arr_size);
cout << "pos=" << pos << endl;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}