C++ STL算法系列4---unique , unique_copy函数

 一.unique函数

类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素

该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序改变了),表示无重复的值范围得结束。

 1 // sort words alphabetically so we can find the duplicates 
 2 sort(words.begin(), words.end()); 
 3      /* eliminate duplicate words: 
 4       * unique reorders words so that each word appears once in the 
 5       *    front portion of words and returns an iterator one past the 
 6 unique range; 
 7       * erase uses a vector operation to remove the nonunique elements 
 8       */ 
 9  vector<string>::iterator end_unique =  unique(words.begin(), words.end()); 
10  words.erase(end_unique, words.end());

在STL中unique函数是一个去重函数, unique的功能是去除相邻的重复元素(只保留一个),其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,然后 返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。

若调用sort后,vector的对象的元素按次序排列如下:

sort  jumps  over quick  red  red  slow  the  the turtle

则调用unique后,vector中存储的内容是:

注意,words的大小并没有改变,依然保存着10个元素;只是这些元素的顺序改变了。调用unique“删除”了相邻的重复值。给“删除”加上引号是因为unique实际上并没有删除任何元素,而是将无重复的元素复制到序列的前段,从而覆盖相邻的重复元素。unique返回的迭代器指向超出无重复的元素范围末端的下一个位置。

注意:算法不直接修改容器的大小。如果需要添加或删除元素,则必须使用容器操作。

example:

 1 #include <iostream>
 2 #include <cassert>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <string>
 6 #include <iterator>
 7  using namespace std;
 8 
 9  int main()
10 {
11     //cout<<"Illustrating the generic unique algorithm."<<endl;
12     const int N=11;
13     int array1[N]={1,2,0,3,3,0,7,7,7,0,8};
14     vector<int> vector1;
15     for (int i=0;i<N;++i)
16         vector1.push_back(array1[i]);
17 
18     vector<int>::iterator new_end;
19     new_end=unique(vector1.begin(),vector1.end());    //"删除"相邻的重复元素
20     assert(vector1.size()==N);
21 
22     vector1.erase(new_end,vector1.end());  //删除(真正的删除)重复的元素
23     copy(vector1.begin(),vector1.end(),ostream_iterator<int>(cout," "));
24     cout<<endl;
25 
26     return 0;
27 }

运行结果为:

二、unique_copy函数

算法标准库定义了一个名为unique_copy的函数,其操作类似于unique。

唯一的区别在于:前者接受第三个迭代器实参,用于指定复制不重复元素的目标序列。

unique_copy根据字面意思就是去除重复元素再执行copy运算。

编写程序使用unique_copy将一个list对象中不重复的元素赋值到一个空的vector对象中。

 1 //使用unique_copy算法
 2 //将一个list对象中不重复的元素赋值到一个空的vector对象中
 3 #include<iostream>
 4 #include<list>
 5 #include<vector>
 6 #include<algorithm>
 7 using namespace std;
 8 
 9 int main()
10 {
11     int ia[7] = {5 , 2 , 2 , 2 , 100 , 5 , 2};
12     list<int> ilst(ia , ia + 7);
13     vector<int> ivec;
14 
15     //将list对象ilst中不重复的元素复制到空的vector对象ivec中
16     //sort(ilst.begin() , ilst.end());  //不能用此种排序,会报错
17     ilst.sort();  //在进行复制之前要先排序,切记
18     unique_copy(ilst.begin() , ilst.end() , back_inserter(ivec));
19 
20     //输出vector容器
21     cout<<"vector: "<<endl;
22     for(vector<int>::iterator iter = ivec.begin() ; iter != ivec.end() ; ++iter)
23         cout<<*iter<<" ";
24     cout<<endl;
25 
26     return 0;
27 }

 假如

list<int> ilst(ia , ia + 7);
改为:vector<int> ilst(ia , ia + 7);

则排序时可用:

sort(ilst.begin() , ilst.end());

 这里要注意list和vector的排序用什么方法。

《Effective STL》里这些话可能有用处:item 31    “我们总结一下你的排序选择:   ● 如果你需要在vector、string、deque或数组上进行完全排序,你可以使用sort或stable_sort。   ● 如果你有一个vector、string、deque或数组,你只需要排序前n个元素,应该用partial_sort。   ● 如果你有一个vector、string、deque或数组,你需要鉴别出第n个元素或你需要鉴别出最前的n个元素,而不用知道它们的顺序,nth_element是你应该注意和调用的。   ● 如果你需要把标准序列容器的元素或数组分隔为满足和不满足某个标准,你大概就要找partition或stable_partition。   ● 如果你的数据是在list中,你可以直接使用partition和stable_partition,你可以使用list的sort来代替sort和stable_sort。如果你需要partial_sort或nth_element提供的效果,你就必须间接完成这个任务,但正如我在上面勾画的,会有很多选择。    另外,你可以通过把数据放在标准关联容器中的方法以保持在任何时候东西都有序。你也可能会考虑标准非STL容器priority_queue,它也可以总是保持它的元素有序。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一“技”之长

分分钟使用正则表达式 原

        从概念上来说,正则表达式也是一门小巧而精炼的语言,它可以用来简化检索特定的字符串,替换特定字符等功能,有许多开发语言工具,都内嵌支持正则表达式。...

8630
来自专栏积累沉淀

Python快速学习第四天

第四天: 条件 、循环和其他语句 1、    print 使用逗号输出 - 打印多个表达式也是可行的,但要用逗号隔开 >>> print 'tanggao ',...

201100
来自专栏河湾欢儿的专栏

第五节正则

9620
来自专栏coding for love

待整理01-JS 形参与变量声明和函数声明同名怎么办?

前两天遇到一道很有意思的题目,乍看起来是一道考声明提升和变量提升的题目的,但事实上还包含了更多的知识点。下面我们一起来看一下。

12330
来自专栏PHP在线

PHP部分字符串函数汇总

我们大家知道无论哪种语言,字符串操作都是一个重要的基础,往往是简单而重要。PHP给我们提供了大量的字符串操作函数,功能强大,使用也比较简单,这里为大家总结九类字...

36560
来自专栏生信小驿站

python-运算符与表达式

你所编写的大多数语句(逻辑行)都包含了表达式(Expressions)。一个表达式的简单例子便是 2+3。表达式可以拆分成运算符(Operators)与操作数(...

22320
来自专栏cs

c++13.0 STL[stack,queue,set,dequeue]

set相关知识点: ---- set:集合,红黑树实现 特点: 1.0 内部的元素根据其值自动排序。 2.0 内部元素只能出现一次。 set数据结...

25060
来自专栏ml

nyoj-----前缀式计算

前缀式计算 时间限制:1000 ms  |           内存限制:65535 KB 难度:3 描述 先说明一下什么是中缀式: 如2+(3+4)*5这种我...

34760
来自专栏编程

Shell 数组

Shell中数据类型不多,比如说字符串,数字类型,数组。数组是其中比较重要的一种,同时Shell中的数组不像JAVA/C,只能是一维数组,没有二维数组;数组元素...

21800
来自专栏Java帮帮-微信公众号-技术文章全总结

第四天 数组【悟空教程】

22490

扫码关注云+社区

领取腾讯云代金券