STL中与比较器有关的容器和算法

来源:互联网 发布:人工智能产业链股票 编辑:程序博客网 时间:2024/04/28 16:21

 

一. set:包含了经过排序了的数据,这些数据的值(value)必须是唯一的。 

  • 头文件: #include<set>
  • 定义:定义一个元素为整数的集合a,可以用 set<int> a;
  • 基本操作:
  1. 对集合a中元素的有
  2. 插入元素:a.insert(1);
  3. 删除元素(如果存在):a.erase(1);
  4. 判断元素是否属于集合:if (a.find(1) != a.end()) ...
  5. 返回集合元素的个数:a.size()
  6. 将集合清为空集:a.clear()
  7. 集合的并,交和差

  set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

  (注意在此前要将c清为空集)。

  • 默认情况:输出的结果从小到大,即15, 25, 35, 55; 若要从大到小输出,则这样定义集合:set<Teacher, greater<Teacher>> teachers; 输出的结果为:55, 35, 25, 15。
  • 注意以下几点:
  1. 对于内置类型如int, double, float, string等,比较器以及输入输出操作符是系统已经定义好的;对于class, struct等类型,比较器即输入输出操作符都需重新写;如struct Teacher里面定义了比较器及重载输出操作符;
  2. set里面的元素有序且唯一,在默认的情况下,是按从小到大排序的;如果想让元素从大到小排序,则需要在定义集合时,模板参数中需加greater比较器,而且这里的参数是结构体本身,因此是greater<Teacher>,而不是对象greater<Teacher>();但是在sort函数中的比较器,则是对象。

 

 

  • 例子程序:

 

 

二. 输入输出重新定向

 

  • 例子程序:

 

  • 说明:若main中只有语句(3), 则直接执行OutputInfo(),并且将内容输入到屏幕上;
  • 问题:若不想改变函数本身,如何将OutputInfo()中的语句输入到outfile这个文件中,即语句(1)所建的文件?
  • 答: 加上第(2)和(4)语句;

三. priority_queue: 优先队列

  • 头文件: #include<queue>
  • 模板原型:priority_queue<T,Sequence,Compare>
  1. T:存放容器的元素类型
  2. Sequence:实现优先级队列的底层容器,默认是vector<T>
  3. Compare:用于实现优先级的比较函数,默认是functional中的less<T>
  • 基本操作:
  1. empty()  如果优先队列为空,则返回真 
  2. pop()  删除第一个元素 
  3. push()  加入一个元素 
  4. size()  返回优先队列中拥有的元素的个数 
  5. top()  返回优先队列中有最高优先级的元素 

 

  • 注意一下几点:
  1.  priority_queue放置元素时,不会判断元素是否重复。(因为在模板的第二个参数是顺序容器,不能保证元素的唯一性)
  2.  默认情况下(默认比较器是less),大的优先,即按顺序输出是从大到小的;
  3.  若要从小到大输出,则在定义优先队列对象时,模板参数上要加大于比较器;由于优先队列模板参数有三个,所以若加比较器作为参数,则第二个参数也不能省,一般就用默认的vector<>;
  4. 优先队列默认的情况是从大到小的顺序,而sort, binary_search 以及set 默认的都是从小到大排序的。

 

  • 例子程序:

此代码输出结果为: 25, 15, 10, 5;

 

下面讲有关排序方面的4个算法:

一. sort

  • 头文件: #include <algorithm>
  • 例子程序:

  • 注意:比较函数放在头文件<functional>中。

 

二. binary_search: 二分搜索法,要求容器是从小到大排序的,若从大到小排序了,它会找不到;它返回的是一个bool值,表示有没有找到

 

  •  

    头文件: #include <algorithm>

 

  •  

    例子程序:

     

 

 

若sort(datas.begin(), datas.end(), greater<int>());//将datas从大到小排序

bool temp = binary_search(datas.begin(), datas.end(), 0); //返回0,即没有找到,此种情况下,可以将迭代器反过来,即

bool temp = binary_search(datas.rbegin(), datas.rend(), 0); //这样就相当于又是对从小到大排序的数组进行操作了


 

三. unique: 保证数的唯一性,但是不能保证数的有序;返回一个迭代器,指向数据唯一的末端。

 

  •  

     

    头文件: #include <algorithm>

 

 

  •  

     

    例子程序:

     

     

 

 

 

 

 

 

 

 

 

 

 

 

 

或者

 

 

 

四. unique_copy: 保证数的唯一性,并执行拷贝操作

  • 用法看例子程序:

 

 

 

注意: datas中有元素1000个,经过唯一化后,元素必然小于等于1000;所以当afterUnique空间赋予过大时,后面的元素将会用0补;

 

  • 为避免这种情况,我们可以用插入迭代器,即边插入边分配空间。

 

 

 

 

 

  • 下面介绍几种插入迭代器:插入迭代器提供三个适配器函数,返回类型为insert_iterator类型
  1. back_inserter() 它使用容器的push_back()插入操作,如 unique_copy( ivec.begin(), ivec.end(),back_inserter( afterUnique );//现在用 afterUnique.push_back()
  2. 插入front_inserter() 它使用容器的push_front()插入操作,但是注意vector 类不支持push_front()
  3. inserter() 它调用容器的insert()插入操作代替赋值操作符inserter()要求两个实参

 

原创粉丝点击