天天看点

标准模板库(STL)学习指南之set集合

set是关联容器。其键值就是实值,实值就是键值,不可以有重复,所以我们不能通过set的迭代器来改变set的元素的值,set拥有和list相同的特性:当对他进行插入和删除操作的时候,操作之前的迭代器依然有效。当然删除了的那个就没效了。set的底层结构是RB-tree,所以是有序的。

   stl中特别提供了一种针对set的操作的算法:交集set_intersection,并集set_union,差集set_difference。对称差集set_symeetric_difference,这些算法稍后会讲到。

一:set模板类的声明。

<code>template</code> <code>&lt;</code>

<code>   </code><code>class</code> <code>key</code>

<code>   </code><code>class</code> <code>=Traitsless&lt;key&gt;</code>

<code>   </code><code>class</code> <code>Allocator=allocator&lt;key&gt;</code>

<code>&gt;</code>

<code>class</code> <code>set。</code>

其中个参数的意义如下:

key:要放入set里的数据类型,可以是任何类型的数据。

Traits:这是一个仿函数(关于仿函数是什么,我后面的文章会讲到)。提供了具有比较功能的仿函数,来觉得元素在set里的排列的顺序,这是一个可选的参数,默认的是std::less&lt;key&gt;,如果要自己提供这个参数,那么必须要遵循此规则:具有两个参数,返回类型为bool。

Allocator:空间配置器,这个参数是可选的,默认的是std::allocator&lt;key&gt;.

二:set里的基本操作

我们可以通过下面的方法来实例化一个set对象

std::set&lt;int&gt; s;那个s这个对象里面存贮的元素是从小到大排序的,(因为用std::less作为比较工具。)

如果要想在s里面插入数据,可以用inset函数(set没用重载[]操作,因为set本生的值和索引是相同的)

s.insert(3);s.insert(5).....

因为set是集合,那么集合本身就要求是唯一性,所以如果要像set里面插入数据和以前的数据有重合,那么插入不成功。

可以通过下面的方法来遍历set里面的元素

<code>std::set&lt;</code><code>int</code><code>&gt;::iterator it = s.begin();</code>

<code>while</code><code>(it!=s.end())</code>

<code>{</code>

<code>   </code><code>cout&lt;&lt;*it++&lt;&lt;endl;</code><code>//迭代器依次后移,直到末尾。</code>

<code>}</code>

如果要查找一个元素用find函数,it = s.find(3);这样it是指向3的那个元素的。可以通过rbegin,rend来逆向遍历

<code>std::set&lt;</code><code>int</code><code>&gt;::reverse_iterator it = s.rbegin();</code>

<code>while</code><code>(it!=s.rend())</code>

<code>  cout&lt;&lt;*it++&lt;&lt;endl;</code>

还有其他的一些操作在这就不一一列出了。

三:set向量的使用实例

<code>#include &lt;iostream&gt;</code>

<code>#include &lt;string&gt;</code>

<code>#include &lt;set&gt;</code>

<code>#include &lt;algorithm&gt;</code>

<code>#include &lt;iterator&gt;</code>

<code>using</code> <code>namespace</code> <code>std;</code>

<code>/* 联合容器将值与关键字联合在一起,使用关键字来查找值,</code>

<code>* 提供元素的快速访问,插入元素不能指定位置,容器自动处理插入位置</code>

<code>* STL 提供四种联合容器:set、multiset、map、multimap</code>

<code>* set、multiset 存储一种元素,前者关键字不可重复,后者关键字可以重复。</code>

<code>* map、multimap 存储一对元素键与值,前者关键字不可重复,后者关键字可以重复。</code>

<code>*/</code>

<code>int</code> <code>main()</code>

<code>    </code><code>const</code> <code>int</code> <code>N = 3;</code>

<code>    </code><code>string s1[N] = {</code><code>"xp"</code><code>,</code><code>"python"</code><code>,</code><code>"linux"</code><code>};</code>

<code>    </code><code>string s2[N] = {</code><code>"python"</code><code>,</code><code>"php"</code><code>,</code><code>"perl"</code><code>};</code>

<code>    </code><code>set&lt;string&gt; sa(s1, s1 + N);</code><code>// 声明一个集合sa,元素为数组s1</code>

<code>    </code><code>set&lt;string&gt; sb(s2, s2 + N);</code><code>// 声明一个集合sb,元素为数组s2</code>

<code>    </code><code>set&lt;string&gt; sc;</code><code>// 声明一个空集合sc</code>

<code>    </code><code>ostream_iterator&lt;string, </code><code>char</code><code>&gt; out (cout, </code><code>" "</code><code>);</code>

<code>    </code><code>copy(sa.begin(), sa.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set sa"</code><code>&lt;&lt; endl;</code>

<code>    </code><code>copy(sb.begin(), sb.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set sb"</code><code>&lt;&lt; endl;</code>

<code>    </code><code>set_union(sa.begin(), sa.end(), sb.begin(), sb.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set_union() 并集"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>set_intersection(sa.begin(), sa.end(), sb.begin(), sb.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set_intersection() 交集"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>set_difference(sa.begin(), sa.end(), sb.begin(), sb.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set_difference() 集合的差"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>set_difference(sb.begin(), sb.end(), sa.begin(), sa.end(), out);</code>

<code>    </code><code>set_union(sa.begin(), sa.end(), sb.begin(), sb.end(), insert_iterator&lt;set&lt;string&gt; &gt;(sc, sc.begin() ));</code>

<code>    </code><code>sc.insert(</code><code>"delphi"</code><code>);</code>

<code>    </code><code>copy(sc.begin(), sc.end(), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;set sc"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>copy(sc.lower_bound(</code><code>"perl"</code><code>), sc.upper_bound(</code><code>"python"</code><code>), out);</code>

<code>    </code><code>cout &lt;&lt; </code><code>"-&gt;显示集合区间"</code> <code>&lt;&lt; endl;</code>

<code>    </code><code>return</code> <code>0;</code>