二分法
二分查找原理很简单 , 大家高中的时候 就学过 就不多说了 下面附上 二分的代码
在已经有序的数组 d 里面 , 找到一个 大小为 num 的数字 , 数组的长度是 len
1 int erfen(int num,int len) // 在 已经确定的 数列里面 2 { 3 int left,right,mid; // 找到 要么可以替换的 数字要么 向后推一位 4 left=1; 5 right=len; 6 mid=(left+right)/2; 7 while(left<=right) 8 { 9 if(d[mid]<num) 10 left=mid+1; 11 else if(d[mid]>num) 12 right=mid-1; 13 else 14 return mid; 15 mid=(left+right)/2; 16 } 17 return left; 18 }
这个是自己写的函数 , 感觉自己写的 不如 stl 函数库中的 , 下面附上 , stl 函数中的 二分查找的 各种函数 . STL中关于二分查找的函数有三个lower_bound 、upper_bound 、binary_search 。这三个函数都运用于有序区间(当然这也是运用二分查找的前提)。
迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。
STL中关于二分查找的函数有三个lower_bound 、upper_bound 、binary_search 。这三个函数都运用于有序区间(当然这也是运用二分查找的前提)。
其中如果寻找的value存在,那么lower_bound返回一个迭代器指向其中第一个这个元素。upper_bound返回一个迭代器指向其中最后一个这个元素的下一个位置(明确点说就是返回在不破坏顺序的情况下,可插入value的最后一个位置)。如果寻找的value不存在,那么lower_bound和upper_bound都返回“假设这样的元素存在时应该出现的位置”。要指出的是lower_bound和upper_bound在源码中只是变换了if—else语句判定条件的顺序,就产生了最终迭代器位置不同的效果。
binary_search试图在已排序的[first,last)中寻找元素value,若存在就返回true,若不存在则返回false。返回单纯的布尔值也许不能满足需求,而lower_bound、upper_bound能提供额外的信息。事实上由源码可知binary_search便是利用lower_bound求出元素应该出现的位置,然后再比较该位置 的值与value的值。该函数有两个版本一个是operator< ,另外一个是利用仿函数comp进行比较。
先上lower_bound 它既可以返回第一个比查找数字大的值 , 也可以返回第一个 该数字的位置 , 下面先 附上 返回位置的代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<set> 9 #include<stack> 10 #include<string> 11 #include<sstream> 12 #include<map> 13 #include<cctype> 14 using namespace std; // 二分查找 , 效率挺高的 , 下面是 stl 中 二分查找的 代码 15 int main() 16 { 17 int a[10]; 18 for(int i=0;i<10;i++) 19 a[i]=2*i; 20 int n; 21 sort(a,a+10); 22 int location; 23 while(scanf("%d",&n)) 24 { 25 location=lower_bound(a,a+10,n)-a; // 如果 location 是 指针的话 返回的 就是 值 , 如果不是指针的话 返回的就是 位置 26 printf("%d\n",location); 27 } 28 return 0; 29 }
fa
返回 值的情况
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<set> #include<stack> #include<string> #include<sstream> #include<map> #include<cctype> using namespace std; int main() { int a[10]; for(int i=0;i<10;i++) a[i]=2*i; int n; sort(a,a+10); int *location; while(scanf("%d",&n)) { location=lower_bound(a,a+10,n); // 缺点是 , 如果查找的数字 过大的话 返回的是 那个比较大的数字 . printf("%d\n",*location); } return 0; }
下面附上 upper_bound 的应用方式 (upper_bound返回一个迭代器指向其中最后一个这个元素的下一个位置(明确点说就是返回在不破坏顺序的情况下,可插入value的最后一个位置) 剩下的 都 一样
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<set> #include<stack> #include<string> #include<sstream> #include<map> #include<cctype> using namespace std; int main() { int a[10]; for(int i=0;i<10;i++) a[i]=5; int n; sort(a,a+10); int location; while(scanf("%d",&n)) { location=upper_bound(a,a+10,n)-a; // 缺点是 , 如果查找的数字 过大的话 返回的是 那个比较大的数字 . printf("%d\n",location); } return 0; }