二分查找(手写和自带函数)(从小到大的序列:第一个大于x的数/第一个大于等于x的数/第一个等于x的数/小于x的数中,最右边的数/小于等于x的数中,最右边的数 ; 从大到小的序列:第一个小于x的数/第一个小于等于x的数/第一个等于x的数/大于x的数中,最右边的数/大于等于x的数中,最右边的数)

 

  1 /**
  2 1. rightmost_smaller,那肯定是第一个啊。所以不成立! : 应该是小于x的数最靠右的那个
  3 2. 两个方法,a. 手写二分while (l<r)... b.binary_search函数upper_bound和lower_bound。它们互相对照
  4 3. 手写二分
  5     (可以很容易回想起来的,容易记住的)
  6     a. l+1 r-1 <= 为了能够可以退出
  7     b. 数组是从0还是1开始的 sort(a,a+n) sort(a+1,a+n) 然后upper_bound这些,是对应指a/a+1后的第几个
  8     c. 边界问题,怎么样才是没有找到:最后找到最右边结束也没找到
  9 **/
 10 
 11 
 12 #include <cstdio>
 13 #include <cstdlib>
 14 #include <cstring>
 15 #include <cmath>
 16 #include <cstdbool>
 17 #include <string>
 18 #include <algorithm>
 19 #include <iostream>
 20 #include <sstream>
 21 #include <ctime>
 22 #include <stack>
 23 #include <vector>
 24 #include <queue>
 25 #include <set>
 26 #include <map>
 27 using namespace std;
 28 #define ll long long
 29 #define ull unsigned long long
 30 
 31 const ll mod_1=1e9+7;
 32 const ll mod_2=998244353;
 33 
 34 const double eps_1=1e-5;
 35 const double eps_2=1e-10;
 36 
 37 const int maxn=2e5+10;
 38 
 39 //int a[maxn],n;
 40 
 41 int n=10;
 42 int a[11]={0,1,2,3,4,5,6,7,8,9,10};
 43 int a_rev[11];
 44 
 45 //0,1,1,2,2,2,3,4,4,5
 46 
 47 /*
 48 lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
 49 
 50 upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
 51 
 52 ————————————————
 53                             版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
 54 
 55 原文链接:https://blog.csdn.net/qq_40160605/article/details/80150252
 56 */
 57 
 58 /*
 59 1.排序和建堆的效果
 60 排序:
 61 less<T>变成升序(从左到右遍历下标时,数组元素是从小到大)
 62 greater<T>变成降序(从左到右遍历下标时,数组元素是从大到小)
 63 建堆:
 64 less<T>变成大顶堆(从上层到下层,堆元素是从大到小,同层之间随便)
 65 greater<T>变成小顶堆(从上层到下层,堆元素是从小到大,同层之间随便)
 66 可以看到排序和建队时,less和greater并不是直接对应汉语意思,不能统一。其实是真正的意思是两个要比较的元素,第一个元素是否比第二个元素更小less还是更大greater。
 67 ————————————————
 68 
 69                             版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
 70 
 71 原文链接:https://blog.csdn.net/sandalphon4869/article/details/105419706
 72 */
 73 
 74 
 75 
 76 ///---------------///
 77 
 78 ///binary_search函数upper_bound和lower_bound
 79 
 80 int way2_first_larger(int x)
 81 {
 82     ///从小到大的序列:第一个大于x的数
 83     int index = upper_bound(a+1,a+n+1,x) - (a+1);
 84 
 85     if (index==n)
 86         return -1;
 87     else
 88         return index+1;
 89 
 90 }
 91 
 92 int way2_first_larger_than_or_equal(int x)
 93 {
 94     ///从小到大的序列:第一个大于等于x的数
 95     int index = lower_bound(a+1,a+n+1,x) - (a+1);
 96 
 97     if (index==n)
 98         return -1;
 99     else
100         return index+1;
101 }
102 
103 int way2_first_equal(int x)
104 {
105     ///从小到大的序列:第一个等于x的数
106     int index = lower_bound(a+1,a+n+1,x) - (a+1);
107     if (index==n || a[index+1]!=x)
108         return -1;
109     else
110         return index+1;
111 }
112 
113 int way2_rightmost_smaller(int x)
114 {
115     ///从小到大的序列:小于x的数中,最右边的数
116     int index = lower_bound(a+1,a+n+1,x) - (a+1);
117     if (index==0)
118         return -1;
119     else
120         return index;
121 }
122 
123 int way2_rightmost_smaller_or_equal(int x)
124 {
125     ///从小到大的序列:小于等于x的数中,最右边的数
126     int index = upper_bound(a+1,a+n+1,x) - (a+1);
127 
128     if (index==0)
129         return -1;
130     else
131         return index;
132 }
133 
134 
135 
136 ///---------------///
137 
138 
139 ///手写二分
140 
141 int first_larger(int x)
142 {
143     ///从小到大的序列:第一个大于x的数
144 
145     int l,r,mid;
146     l=1;
147     r=n;
148 
149     while (l<=r)
150     {
151         mid=(l+r)/2;
152 
153         //如果没有实现,改为要到实现
154         if (a[mid]<=x)
155             l=mid+1;
156         else
157             r=mid-1;
158     }
159 
160     if (l==n+1)
161         return -1;
162     else
163         return l;
164 }
165 
166 
167 int first_larger_than_or_equal(int x)
168 {
169     ///从小到大的序列:第一个大于等于x的数
170 
171     int l,r,mid;
172     l=1;
173     r=n;
174 
175     while (l<=r)
176     {
177         mid=(l+r)/2;
178 
179         //如果没有实现,改为要到实现
180         if (a[mid]<x)
181             l=mid+1;
182         else
183             r=mid-1;
184     }
185 
186     if (l==n+1)
187         return -1;
188     else
189         return l;
190 }
191 
192 int first_equal(int x)
193 {
194     ///从小到大的序列:第一个等于x的数
195 
196     int l,r,mid;
197     l=1;
198     r=n;
199 
200     while (l<=r)
201     {
202         mid=(l+r)/2;
203 
204         //如果没有实现,改为要到实现
205         if (a[mid]<x)
206             l=mid+1;
207         else
208             r=mid-1;
209     }
210 
211     if (l==n+1 || a[l]!=x)
212         return -1;
213     else
214         return l;
215 }
216 
217 
218 int rightmost_smaller(int x)
219 {
220     ///从小到大的序列:小于x的数中,最右边的数
221     ///大于等于x的数,它的最早第一个数
222 
223     int l,r,mid;
224     l=1;
225     r=n;
226 
227     while (l<=r)
228     {
229         mid=(l+r)/2;
230 
231         //如果没有实现,改为要到实现
232         if (a[mid]<x)
233             l=mid+1;
234         else
235             r=mid-1;
236     }
237 
238     if (r==0)
239         return -1;
240     else
241         return l-1;
242 }
243 
244 int rightmost_smaller_or_equal(int x)
245 {
246     ///从小到大的序列:小于等于x的数中,最右边的数
247     ///大于x的数,它的最早第一个数
248 
249     int l,r,mid;
250     l=1;
251     r=n;
252 
253     while (l<=r)
254     {
255         mid=(l+r)/2;
256 
257         //如果没有实现,改为要到实现
258         if (a[mid]<=x)
259             l=mid+1;
260         else
261             r=mid-1;
262     }
263 
264     if (r==0)
265         return -1;
266     else
267         return l-1;
268 }
269 
270 
271 
272 ///---------------///
273 
274 ///binary_search函数upper_bound和lower_bound
275 
276 //descending
277 int des_way2_first_smaller(int x)
278 {
279     ///从大到小的序列:第一个小于x的数
280     int index = upper_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1);
281 
282     if (index==n)
283         return -1;
284     else
285         return index+1;
286 }
287 
288 int des_way2_first_smaller_than_or_equal(int x)
289 {
290     ///从大到小的序列:第一个小于等于x的数
291     int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1);
292 
293     if (index==n)
294         return -1;
295     else
296         return index+1;
297 }
298 
299 int des_way2_first_equal(int x)
300 {
301     ///从大到小的序列:第一个等于x的数
302     int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1);
303 
304     if (index==n || a_rev[index+1]!=x)
305         return -1;
306     else
307         return index+1;
308 }
309 
310 int des_way2_rightmost_larger(int x)
311 {
312     ///从大到小的序列:大于x的数中,最右边的数
313     int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1);
314 
315     if (index==0)
316         return -1;
317     else
318         return index;
319 }
320 
321 int des_way2_rightmost_larger_than_or_equal(int x)
322 {
323     ///从大到小的序列:大于等于x的数中,最右边的数
324     int index = upper_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1);
325 
326     if (index==0)
327         return -1;
328     else
329         return index;
330 }
331 
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 int main()
342 {
343     /**
344     针对 int n=10; int a[11]={0,1,2,3,4,5,6,7,8,9,10};
345     **/
346 
347     if (0)
348     {
349         printf("%d\n", way2_first_larger(-100) ); //1
350         printf("%d\n", way2_first_larger_than_or_equal(-100) );    //1
351 
352         printf("%d\n", way2_first_larger(100) );  //-1
353         printf("%d\n", way2_first_larger_than_or_equal(100) ); //-1
354 
355         printf("%d\n", way2_first_larger(1) ); //2
356         printf("%d\n", way2_first_larger_than_or_equal(1) );    //1
357 
358         printf("%d\n", way2_first_larger(10) ); //-1
359         printf("%d\n", way2_first_larger_than_or_equal(10) );    //10
360 
361         printf("%d\n", way2_first_larger(5) ); //6
362         printf("%d\n", way2_first_larger_than_or_equal(5) );    //5
363 
364 
365         printf("\n---\n\n");
366 
367 
368         printf("%d\n", way2_first_equal(-100) );   //-1
369         printf("%d\n", way2_first_equal(100) );   //-1
370         printf("%d\n", way2_first_equal(4) );   //4
371 
372 
373         printf("\n---\n\n");
374 
375 
376         printf("%d\n", way2_rightmost_smaller(-100) );    //-1
377         printf("%d\n", way2_rightmost_smaller_or_equal(-100) );   //-1
378 
379         printf("%d\n", way2_rightmost_smaller(100) );    //10
380         printf("%d\n", way2_rightmost_smaller_or_equal(100) );   //10
381 
382         printf("%d\n", way2_rightmost_smaller(1) ); //-1
383         printf("%d\n", way2_rightmost_smaller_or_equal(1) );    //1
384 
385         printf("%d\n", way2_rightmost_smaller(10) ); //9
386         printf("%d\n", way2_rightmost_smaller_or_equal(10) );    //10
387 
388         printf("%d\n", way2_rightmost_smaller(5) ); //4
389         printf("%d\n", way2_rightmost_smaller_or_equal(5) );    //5
390 
391         printf("%d\n", way2_rightmost_smaller(2) ); //1
392         printf("%d\n", way2_rightmost_smaller_or_equal(2) );    //2
393 
394     }
395 
396 
397 
398     if (0)
399     {
400         printf("%d\n", first_larger(-100) ); //1
401         printf("%d\n", first_larger_than_or_equal(-100) );    //1
402 
403         printf("%d\n", first_larger(100) );  //-1
404         printf("%d\n", first_larger_than_or_equal(100) ); //-1
405 
406         printf("%d\n", first_larger(1) ); //2
407         printf("%d\n", first_larger_than_or_equal(1) );    //1
408 
409         printf("%d\n", first_larger(10) ); //-1
410         printf("%d\n", first_larger_than_or_equal(10) );    //10
411 
412         printf("%d\n", first_larger(5) ); //6
413         printf("%d\n", first_larger_than_or_equal(5) );    //5
414 
415 
416         printf("\n---\n\n");
417 
418 
419         printf("%d\n", first_equal(-100) );   //-1
420         printf("%d\n", first_equal(100) );   //-1
421         printf("%d\n", first_equal(4) );   //4
422 
423 
424         printf("\n---\n\n");
425 
426 
427         printf("%d\n", rightmost_smaller(-100) );    //-1
428         printf("%d\n", rightmost_smaller_or_equal(-100) );   //-1
429 
430         printf("%d\n", rightmost_smaller(100) );    //10
431         printf("%d\n", rightmost_smaller_or_equal(100) );   //10
432 
433         printf("%d\n", rightmost_smaller(1) ); //-1
434         printf("%d\n", rightmost_smaller_or_equal(1) );    //1
435 
436         printf("%d\n", rightmost_smaller(10) ); //9
437         printf("%d\n", rightmost_smaller_or_equal(10) );    //10
438 
439         printf("%d\n", rightmost_smaller(5) ); //4
440         printf("%d\n", rightmost_smaller_or_equal(5) );    //5
441 
442         printf("%d\n", rightmost_smaller(2) ); //1
443         printf("%d\n", rightmost_smaller_or_equal(2) );    //2
444 
445     }
446 
447 
448 
449     if (0)
450     {
451         copy(a+1, a+n+1, a_rev+1);
452         reverse(a_rev+1, a_rev+n+1);
453 
454         printf("%d\n", des_way2_first_smaller(-100) );  //-1
455         printf("%d\n", des_way2_first_smaller_than_or_equal(-100) );    //-1
456 
457         printf("%d\n", des_way2_first_smaller(100) );   //1
458         printf("%d\n", des_way2_first_smaller_than_or_equal(100) ); //1
459 
460         printf("%d\n", des_way2_first_smaller(1) ); //-1
461         printf("%d\n", des_way2_first_smaller_than_or_equal(1) );   //10
462 
463         printf("%d\n", des_way2_first_smaller(10) );    //2
464         printf("%d\n", des_way2_first_smaller_than_or_equal(10) );  //1
465 
466         printf("%d\n", des_way2_first_smaller(2) ); //10
467         printf("%d\n", des_way2_first_smaller_than_or_equal(2) );   //9
468 
469         printf("%d\n", des_way2_first_smaller(7) ); //5
470         printf("%d\n", des_way2_first_smaller_than_or_equal(7) );   //4
471 
472 
473         printf("\n---\n\n");
474 
475 
476         printf("%d\n", des_way2_first_equal(-100) );   //-1
477         printf("%d\n", des_way2_first_equal(100) );   //-1
478 
479         printf("%d\n", des_way2_first_equal(1) );   //10
480         printf("%d\n", des_way2_first_equal(10) );   //1
481 
482         printf("%d\n", des_way2_first_equal(7) );   //4
483 
484 
485         printf("\n---\n\n");
486 
487 
488         printf("%d\n", des_way2_rightmost_larger(-100) );  //10
489         printf("%d\n", des_way2_rightmost_larger_than_or_equal(-100) );    //10
490 
491         printf("%d\n", des_way2_rightmost_larger(100) );   //-1
492         printf("%d\n", des_way2_rightmost_larger_than_or_equal(100) ); //-1
493 
494         printf("%d\n", des_way2_rightmost_larger(1) ); //9
495         printf("%d\n", des_way2_rightmost_larger_than_or_equal(1) );   //10
496 
497         printf("%d\n", des_way2_rightmost_larger(10) );    //-1
498         printf("%d\n", des_way2_rightmost_larger_than_or_equal(10) );  //1
499 
500         printf("%d\n", des_way2_rightmost_larger(2) ); //8
501         printf("%d\n", des_way2_rightmost_larger_than_or_equal(2) );   //9
502 
503         printf("%d\n", des_way2_rightmost_larger(7) ); //3
504         printf("%d\n", des_way2_rightmost_larger_than_or_equal(7) );   //4
505     }
506 
507 
508 
509 
510 
511     return 0;
512 }

 

过去的:二分查找(等于x,小于x,小于等于x,大于x,大于等于x ) - congmingyige - 博客园 (cnblogs.com)

posted @ 2024-03-27 03:04  congmingyige  阅读(17)  评论(0编辑  收藏  举报