pat每日刷题计划--day70

二分法

  • binarySearch找的是出现在a数组中的,数值等于num的数的下标。(有多个的时候是随机的输出了一个)
  • lowerbound找的是在a数组中出现的第一个,数值大于等于num的数的下标
  • upperbound找的是a数组中出现的第一个,数值大于num的数的下标

找具体的某个数,是使用mid进行判断,而另外的两个是使用的left和right夹逼。

也正是因此,根据定义可以判断,在binarySearch中,不是对应返回值的a[mid]里面一定不包含正确答案,所以在转移的过程中不需要带上mid

在递增序列里面,binarySearch在a[mid]变迁:

  • a[mid]==num ----> return mid
  • a[mid]>num  ----> right=mid-1
  • a[mid]<num  ---->left=mid+1
  • 判定条件:left<=right,(只要mid,left,right都是合法的就有可能,因此需要带上等号)

而在lowerbound中,最终的一个位置是left==right,然后返回left的下标,在走完数组之前,并不知道当前的位置是真正的第一个。

  • a[mid]>=num  ----> 结果一定在[left,mid]中,right=mid
  • a[mid]<num ---->可以确定mid处是不可能的,所以left=mid+1
  • 循环条件:left<right 因为这样最后一次出来的是left=right

在upperbound中,最终也是left==right

  • a[mid]>num ---->结果一定在[left,mid]中,right=mid
  • a[mid]<=num ---->mid是不在范围内的,left=mid+1
  • 循环判定:left<=right,最终以left=right退出循环

lowerbound和upperbound都可以被称为:寻找有序序列中第一个满足某条件元素的位置,只要设置好对应的边界判定就可以完成转换

binarySearch对应的判断问题是:判断一个有序序列中是否存在某个元素,如存在找出位置

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int binarySearch(int a[],int left,int right,int num)//找出num在a数组的位置
{
    int mid=(left+right)/2;
    while(left<=right)
    {
        mid=(left+right)/2;
        if(a[mid]==num)
            return mid;
        if(a[mid]>num)
            right=mid-1;
        else
            left=mid+1;
    }
    return -1;
}
int lowerbound(int a[],int left,int right,int num)//找出大于等于num的第一个数在a数组的位置
{
    int mid=(left+right)/2;
    while(left<right)
    {
        mid=(left+right)/2;
        if(a[mid]>=num)
        {
            right=mid;
        }
        else
            left=mid+1;
    }
    return left;
}
int upperbound(int a[],int left,int right,int num)//找出第一个大于num的数在a数组中的位置
{
    int mid=(left+right)/2;
    while(left<right)
    {
        mid=(left+right)/2;
        if(a[mid]>num)
            right=mid;
        else
            left=mid+1;
    }
    return left;
}
int main()
{
    int n=5;
    int a[15]={1,3,3,3,6};
    /*for(int i=0;i<n;i++)
        scanf("%d",&a[i]);*/
    printf("%d\n",binarySearch(a,0,n-1,3));
    printf("%d\n",lowerbound(a,0,n-1,3));
    printf("%d\n",upperbound(a,0,n-1,3));
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/tingxilin/p/12241755.html