• STL中algorithm里的查找


    首先,选择查找算法时,区间是否排序是一个至关重要的因素。
    可以按是否需要排序区间分为两组:
     A. count,find
     B. binary_search,lower_bound,upper_bound,equal_range
    A组不需排序区间, B组需要排序区间。
    当一个区间被排序,优先选择B组,因为他们提供对数时间的效率。而A则是线性时间(其实就是从头到尾进行遍历)。

    另外A组B组所依赖的查找判断法则不同,A使用相等性法则(查找对象需要定义operator==), B使用等价性法则(查找对象需要定义operator<,必须在相等时返回false)。

    A组的区别
    count:计算对象区间中的数目。
    find:返回第一个对象的位置。
    查找成功的话,find会立即返回,count不会立即返回(直到查找完整个区间),此时find效率较高。
    因此除非是要计算对象的数目,否则不考虑count。

    B组的区别

    在排完序的数组中查找元素x,如何描述元素x的位置:用lower_bound表示x的下界,用upper_bound表示x的上界.也就是说要用一个区间来表示元素x的位置[lower_bound,upper_bound).看清楚了,这是一个前闭后开区间


    binary_search:判断是否存在某个对象,并不能确定要查找的元素的位置.
    lower_bound: 返回>=对象的第一个位置;
    upper_bound: 返回>对象的第一个位置;
    equal_range: 返回由lower_bound和upper_bound返回值构成的pair,也就是所有等价元素区间。

    int lower(int *a, int sz, int x){
        int l = 0, r = sz;
        while (l^r){
            int mid = (l + r) >> 1;
            if (a[mid] < x)l = mid + 1;
            else r=mid;
        }
        return l;
    }
    int upper(int *a, int sz, int x){
        int l = 0, r = sz;
        while (l^r){
            int mid = (l + r) >> 1;
            if (a[mid] <= x)l = mid + 1;
            else r = mid;
        }
        return l;
    }

    如上代码所示,lower_bound和upper_bound的区别就在于左指针l是小于还是小于等于.

    二分代码有一个关键的地方:必须让l=mid+1.而不能写成l=mid,因为这会导致一个死循环:当l+1=r时,mid=(l+r)>>1=l.这就导致l,r不再发生变化,成死循环了.

    equal_range有两个需要注意的地方:
     1. 如果返回的两个迭代器相同,说明查找区间为空,没有这样的值
     2. 返回迭代器间的距离与迭代器中对象数目是相等的,对于排序区间,他完成了count和find的双重任务

    3.因为equal_range的作用相当于lower_bound和upper_bound之和,所以如果用到这两者时,尽量用equal_range,这样的效率为lgn,而分开使用的复杂度为2*lgn.

       int a[] = {1,2,3,3,3,4,7};
        int n = 7;
        pair<int*,int*>ans=equal_range(a, a + n, 3);
        cout << ans.first - a << " " << ans.second - a << endl;

    输出2 5

  • 相关阅读:
    php设计模式-工厂模式(一)
    php Pthread 线程 互斥锁
    php Pthread 多线程 Worker
    PHP多进程实例
    C# this 关键字
    .NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例
    深入理解Static关键字修饰符
    SQL Server 视图
    .NET初识委托
    RSA加密
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/4888739.html
Copyright © 2020-2023  润新知