二分法模板

21 篇文章 0 订阅

原文:https://blog.csdn.net/CCSGTC/article/details/80586181 

 

其实这个完善的二分写法就是开头提到的左开右开写法,但是做了一些小修改。

考虑一种特殊情况,如果数组中的元素都相同 ,  那么查找的时候不一定每次都会返回第一个元素的位置, 用开头的3种正确代码去查找,肯定返回的是正中间元素的位置. ,因此进行了以下修改,修改后的代码,可以在非递减序列中,查找某个元素第一次出现的位置,不存在返回-1

int binary(int array[], int n, int v)
{
    int left, right, middle;
 
 
    left = -1, right = n ;
 
 
    while (  left + 1 != right )
    {
        middle = (left + right) / 2;
 
 
        if (array[middle] >= v)
        {
            right = middle ;
        }
        else 
        {
            left = middle  ;
        }
 
 
 
    }
 
 
    if( right == n || array[right]!= v)
        return -1;
 
    return right;
}

 

寻找上下界:

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<iostream>
#include<set>
using namespace std;

int l[300001], r[300001];

int main(){
	int n,v;
	int a[300001];
	cin>>n>>v;
	for(int i=0;i<n;i++) cin>>a[i];
	int pre,later;
	int middle;
	int left=-1,right=n;
    //下界
	while(left+1!=right){
		middle=(left+right)/2;
		if (a[middle] >= v)
        {
            right = middle;
        }
        else 
        {
            left = middle;
        }

	}
	pre=right;
    //上界
	left=-1,right=n;
	while(left+1!=right){
		middle=(left+right)/2;
		if (a[middle] <= v)
        {
            left = middle;
        }
        else 
        {
            right = middle;
        }

	}
	later=left;
	cout<<pre<<' '<<later;
    return 0;
} 

/*

10 3
1 2 2 3 3 3 3 4 4 4

*/

 

 

原文链接:https://www.cnblogs.com/Tang-tangt/p/9291018.html

C++ lower_bound 与 upper_bound 函数

头文件: #include  <algorithm>

 

二分查找的函数有 3 个: 参考:C++ lower_bound 和upper_bound

lower_bound(起始地址,结束地址,要查找的数值) 返回的是数值 第一个 出现的位置。

upper_bound(起始地址,结束地址,要查找的数值) 返回的是数值 最后一个 出现的位置。

binary_search(起始地址,结束地址,要查找的数值)  返回的是是否存在这么一个数,是一个bool值

 

 

1  函数lower_bound()  参考:有关lower_bound()函数的使用

 

功能:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置.

注意:如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!

 

2 函数upper_bound()

 

功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置

注意:返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置。同样,如果val大于数组中全部元素,返回的是last。(注意:数组下标越界)

 

PS

        lower_bound(val):返回容器中第一个值【大于或等于】val的元素的iterator位置。

        upper_bound(val): 返回容器中第一个值【大于】

void main()
{
    vector<int> t;
    t.push_back(1);
    t.push_back(2);
    t.push_back(3);
    t.push_back(4);
    t.push_back(6);
    t.push_back(7);
    t.push_back(8);

    
    int low=lower_bound(t.begin(),t.end(),5)-t.begin();
    int upp=upper_bound(t.begin(),t.end(),5)-t.begin();
    cout<<low<<endl;
    cout<<upp<<endl;

    
    system("pause");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值