zoukankan      html  css  js  c++  java
  • bsearch

     

    在java中为了避免 low+high溢出,可以用无符号右移:正数高位补0,负数高位补1

    int mid = (low + high) >>> 1;

    如果是在c++中,那么需要先转换为unsigned的再移位

    int a=100;
    int b;
    b=((unsigned int)a)>>1;

    或者 int mid = low + ((high - low) / 2);

    public static int binarySearch(int[] a, int target) {
     int low = 0;
     int high = a.length - 1;
       while (low <= high) {
         int mid = (low + high) >>> 1;
         int midVal = a[mid];
         if (midVal < target)
             low = mid + 1;
         else if (midVal > target)
             high = mid - 1;
         else
             return mid;
       }
       return -1;
     }
    

      

    C语言中 bsearch 包含在<stdlib.h>头文件中,此函数可以根据你给的条件实现二分查找,如果找到元素则返回指向该元素的指针,否则返回NULL;对于有多个元素匹配成功的情况,bsearch()未定义返回哪一个。使用 bsearch 函数也要自己定义比较子函数。

    函数原型

    void *bsearch(const void *key, const void *base, size_t num, size_t size, int (*cmp)(const void *,const void *));

    解释一下参数

    key 指向要查找的元素

    base 指向进行查找的数组

    num 数组中元素的个数

    size 数组中每个元素的大小,一般用sizeof()表示

    cmp 比较两个元素的函数,定义比较规则。需要注意的是,查找数组必须是经过预先排序的,而排序的规则要和比较子函数cmp的规则相同。

    因为使用bsearch函数要求数组预先排好序,所以该函数通常和快速排序函数(qsort)一起使用,关于qsort函数,详见《C语言标准库函数 qsort 详解

    关于bsearch()的具体应用请见《POJ 2503 Babelfish C语言版

     
    void *
    bsearch (const void *key, //查找项
        const void *base,     //元素数组的起始地址
        size_t nmemb,         //元素的个数
        size_t size,          //每个元素的长度(大小)
         int (*compar) (const void *, const void *)) //比较两个元素的大小的函数
    {
      size_t l, u, idx;
      const void *p;
      int comparison;
    
      l = 0;
      u = nmemb;
      while (l < u)
        {
          idx = (l + u) / 2;    //找出中间点的偏移量,注意(l+u)
          p = (void *) (((const char *) base) + (idx * size)); //找到中间点
          comparison = (*compar) (key, p); //获得中间元素和关键字key之间的额比较值
          if (comparison < 0)              //key小于中间值,落在左边区间,无需移动元素数组的起始地址
              u = idx;                    //只要修改区间长度
          else if (comparison > 0)
              l = idx + 1;                //修改数组元素的起始位置,构成一个新的数组
          else
              return (void *) p;
        }
    
      return NULL;
    }
    

      

    void* Bsearch(void* base, int len, int size, const void* key, int (*cmp)(const void* a, const void* b))
    {
        assert(base != NULL && len >= 0 && size >= 1 && cmp != NULL);
        int low = 0;
        int high = len - 1; 
        while (low <= high) {
            int mid = low + (high - low) / 2;
            char* pmid = (char*)base + mid * size;
            if (cmp(pmid, key) < 0) {
                low = mid + 1;
            } else if (cmp(pmid, key) > 0) {
                high = mid - 1;
            } else {
                return pmid;
            }
    
        }
        return NULL;
    }
    

      

     
     
     
     
     
     
     
     
     
    C语言中可以用bsearch()实现二分查找。同qsort()一样,bsearch()也包含在<stdlib.h>库中,且同样要自定义比较子函数。其原型如下:
     

    void *bsearch(const void *key, const void *base, size_t nmem, size_t size, int (*comp)(constvoid *, const void *));

    key指向所要查找的元素,base指向进行查找的数组,nmem为查找长度,一般为数组长度,size为每个元素所占的字节数,一般用sizeof(...)表示,comp指向比较子函数,它定义比较的规则。需要注意的是,数据必须是经过预先排序的,而排序的规则要和comp所指向比较子函数的规则相同。如果查找成功则返回数组中匹配元素的地址,反之则返回空。对于有多于一个的元素匹配成功的情况,bsearch()未定义返回哪一个。

    例:

    一、对int类型数组排序
    
    int num[100];
    
    int cmp ( const void *a , const void *b )
    {
    return *(int *)a - *(int *)b;
    }
    
    qsort(num,100,sizeof(num[0]),cmp);
    
    二、对char类型数组排序(同int类型)
    
    char word[100];
    
    int cmp( const void *a , const void *b )
    {
    return *(char *)a - *(int *)b;
    }
    
    qsort(word,100,sizeof(word[0]),cmp);
    
    三、对double类型数组排序
    
    double in[100];
    
    int cmp( const void *a , const void *b )
    {
    return *(double *)a > *(double *)b ? 1 : -1;
    }
    
    qsort(in,100,sizeof(in[0]),cmp);
    
    四、对结构体一级排序
    
    struct Sample
    {
    double data;
    int other;
    }s[100]
    
    //按照data的值从小到大将结构体排序
    
    int cmp( const void *a ,const void *b)
    {
    return (*(Sample *)a).data > (*(Sample *)b).data ? 1 : -1;
    }
    
    qsort(s,100,sizeof(s[0]),cmp);
    
    五、对结构体二级排序
    
    struct Sample
    {
    int x;
    int y;
    }s[100];
    
    //按照x从小到大排序,当x相等时按照y从大到小排序
    
    int cmp( const void *a , const void *b )
    {
    struct Sample *c = (Sample *)a;
    struct Sample *d = (Sample *)b;
    if(c->x != d->x) return c->x - d->x;
    else return d->y - c->y;
    }
    
    qsort(s,100,sizeof(s[0]),cmp);
    
    六、对字符串进行排序
    
    struct Sample
    {
    int data;
    char str[100];
    }s[100];
    
    //按照结构体中字符串str的字典顺序排序
    
    int cmp ( const void *a , const void *b )
    {
    return strcmp( (*(Sample *)a).str , (*(Sample *)b).str );
    }
    
    qsort(s,100,sizeof(s[0]),cmp);
    
    附加一个完整点的代码,对字符串二维数组排序:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char s[2001][1001];
    
    int cmp(const void *a, const void *b){
    return strcmp((char *)a,(char *)b);
    }
    
    int main(){
    int i,n;
    scanf("%d",&n);
    getchar();
    for(i=0;i<n;i++) gets(s[i]);
    qsort(s,n,1001*sizeof(char),cmp);
    for(i=0;i<n;i++) puts(s[i]);
    return 0;
    }
    

      

     
     

    #include <stdio.h>
    #include <stdlib.h>

    #define NUM 8

    int compare(const void *p, const void *q)
    {
        return (*(int *)p - *(int *)q);
    }

    int main(int argc, char *argv[])
    {
        int array[NUM] = {9, 2, 7, 11, 3, 87, 34, 6};
        int key = 3;
        int *p;

        
        qsort(array, NUM, sizeof(int), compare);
        p = (int *)bsearch(&key, array, NUM, sizeof(int), compare);

        (p == NULL) ? puts("not found") : puts("found");

        return 0;
    }

  • 相关阅读:
    Springboot单元测试(MockBean||SpyBean)
    使用 Mockito 单元测试 – 教程
    spring结合mockito
    Spatis service单元测试: 使用mock mapper的方式
    单元测试Mockito中的Mock和Spy
    强大的Mockito测试框架
    Mockito单测,mock service层的mapper
    Mockito教程
    SetupFactory 制作安装包
    fiddler的一些记录
  • 原文地址:https://www.cnblogs.com/juandx/p/4075287.html
Copyright © 2011-2022 走看看