zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [POI2011]Lightning Conductor
    [NOI2009]诗人小G

    公告&留言板
    联合省选 2020 题解
    年末时的一些思维碎屑
    RE:ゼロから始める AFO 生活
    退役前的做题记录6.0
    2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解
    300iq Contest 1 简要题解
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/4888739.html
Copyright © 2011-2022 走看看