記兩個std接口equal_range,set_difference


1.equal_range

equal_range是C++ STL中的一種二分查找的算法,試圖在已排序的[first,last)中尋找value,它返回一對迭代器i和j,其中i是在不破壞次序的前提下,value可插入的第一個位置(亦即lower_bound),j則是在不破壞次序的前提下,value可插入的最后一個位置(亦即upper_bound),因此,[i,j)內的每個元素都等同於value,而且[i,j)是[first,last)之中符合此一性質的最大子區間

   如果以稍許不同的角度來思考 equal_range,我們可把它想成是[first,last)內"與value等同"之所有元素形成的區間A,由於[fist,last)有序(sorted),所以我們知道"與value等同"之所有元素一定都相鄰,於是,算法lower_bound返回區間A的第一個迭代器,算法upper_bound返回區間A的最后一個元素的下一個位置, 算法equal_range則是以pair的形式將兩者都返回
   即使[fist,last)並未含有"與value等同"之任何元素,以上敘述仍然合理,這種情況下,"與value等同"之所有元素形成的,其實是一個空區間,在不破壞次序的情況下,只有一個位置可以插入value,而equal_range所返回的pair,其第一和第二(都是迭代器)皆指向該位置。
 
說白了, equal_range就是在一個排序的容器內查找並返回找到的值的區間
// map::equal_elements
#include <iostream>
#include <map>
using namespace std;

int main ()
{
  map<char,int> mymap;
  pair<map<char,int>::iterator,map<char,int>::iterator> ret;

  mymap['a']=10;
  mymap['b']=20;
  mymap['c']=30;

  ret = mymap.equal_range('b');

  cout << "lower bound points to: ";
  cout << ret.first->first << " => " << ret.first->second << endl;

  cout << "upper bound points to: ";
  cout << ret.second->first << " => " << ret.second->second << endl;

  return 0;
}

有些容器內無equal_range方法如vector,則可用std::equal_range方法

    pair<vector<int>::iterator, vector<int>::iterator> ret;
    vector<int> vec_i = { 1, 1, 2, 3, 4 };
    ret = std::equal_range(vec_i.begin(),vec_i.end(),1);

2.set_difference

算法set_difference可以用來求兩個集合的差集,此處的集合可以為std::set,也可以是std::multiset,但是不可以是hash_set以及hash_multiset。為什么呢?因為set_difference要求兩個區間必須是有序的(從小到大排列),std::set和std::multiset為有序序列,而hash_set以及hash_multiset為無序序列。

算法set_difference可構造區間S1,S2的差集(出現於S1但不出現於S2的元素),即S1-S2;返回值為指向輸出區間的尾端。
由於區間S1,S2內的每個元素都不需唯一,因此,如果某個值在S1中出現m次,在S2中出現n次,那么該值在輸出區間中出現的次數為max(m-n,0),且全部來自S1。
  set_difference為穩定操作,即輸出區間內的每個元素的相對順序都和S1內的相對順序相同。

一定謹記:兩個區間必須是有序區間(從小到大)

相似的還有set_union(取兩集合並集)、set_intersection(取兩集合交集)、set_difference(取兩集合差集),參數基本都一樣

int main(void)
{
    int iarr1[]={1,2,3,3,6,7,4,5};
    int iarr2[]={1,4,3,10,9};
    std::sort(begin(iarr1),end(iarr1));
    std::sort(begin(iarr2),end(iarr2));
    vector<int> ivec(10);  
    auto iter=set_difference(begin(iarr1),end(iarr1),begin(iarr2),end(iarr2),ivec.begin());    //ivec為:2,3,5,6,7
    ivec.resize(iter-ivec.begin());//重新確定ivec大小
    return 0;
}

注意,這里1,2參數和3,4參數換位置了ivec結果就不一樣了,現在的結果是iarr1里有而iarr2中沒有的元素。

另外需要注意的是,類似於這樣要在新容器里生成新的元素的方法,一定要申請空間后再調用,不然std的類似方法是不會幫你申請空間的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM