您的位置:首页 > 其它

《 set/map 的使用 ----STL》

2017-11-24 18:14 387 查看
首先,对较简单的
begin()
end()
rbegin()
rend()
等成员的介绍做简单的一笔带过。

begin()
:返回指向集合的第一个元素(升序的第一个元素)的迭代器。

end()
:返回指向集合的最后一个元素后面(升序,一般为NULL的迭代器)的迭代器。

rbegin()
rend()
:类似于
begin()
end()
,不过返回的为逆向的迭代器。

注:以下增删改查都是指在升序下看待。

set:



插入:

//库中键值对pair<class _Ty1,class _Ty2>类似的结构
template<class _Ty1, class _Ty2>
struct pair
{
_Ty1 first;
_Ty2 first;

pair(const _Ty1& _Val1, const _Ty2& _Val2)
: first(_Val1), second(_Val2)
{}
};

//函数参数 value_type 可看做要插入元素的类型。


//(1) pair<iterator, bool> insert(const value_type& val);


参数:
val
为要插入的元素。

返回值:返回键值对
pair<iterator, bool>
类型的的值。若集合中无
val
元素则插入成功,
first
为新插入元素的位置的迭代器,
second
true
,若集合中已有
val
元素则不插入元素,
first
为已存在元素的位置的迭代器,
second
false


//(2) iterator insert(iterator position, const value_type& val);


参数:
position
指定的迭代器位置,
val
position
指定的位置之前插入的元素,注意并不是一定在此位置插入,因为集合中的元素是有顺序的,随便插入会打乱元素顺序,所以可能改变插入的位置。

返回值:返回值指向在集合中新插入的元素或已经存在的具有相同值得元素的位置。

//(3) template <class InputIterator>

//    void insert(InputIterator first, InputIterator last);


模板参数
InputIterator
为迭代器类型,此函数插入一个迭代器区间(左闭右开)的数据。

删除:

//(1) iterator  erase(const_iterator position);


参数:
position
要删除位置的迭代器。

返回值:返回删除元素下一个元素的迭代器,若删除元素为最后一个元素则返回NULL迭代器。

//(2) size_type erase(const value_type& val);


该函数返回已删除
val
元素的个数,对于multiset版本的可以删除多个。

//(3) iterator  erase(const_iterator first, const_iterator last);


该函数删除一段迭代器区间,返回删除区间最后一个元素之后元素的迭代器。

查找:

//iterator       find(const value_type& val);


如果找到值为
val
的元素,就返回此元素的迭代器,若没找到,返回
end()


//iterator lower_bound (const value_type& val);


返回不小于
val
元素的第一个元素,若集合中元素均小于
val
,则返回
end()


//iterator upper_bound (const value_type& val);


返回大于
val
元素的第一个元素,若集合中元素均小于等于
val
,则返回
end()


验证:

#include<iostream>
using namespace std;

#include<set>

void TestSet(){
set<int> s1;
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(3);

//(1) pair<iterator, bool> insert(const value_type& val);

pair<set<int>::iterator, bool> pr;
pr = s1.insert(1);
cout<< "first: " << *(pr.first) << "  second: " << pr.second << endl;

pr = s1.insert(1);
cout << "first: " << *(pr.first) << "  second: " << pr.second << endl;

//(2) iterator insert(iterator position, const value_type& val);
set<int>::iterator it1 = s1.find(4);
set<int>::iterator it2 = s1.insert(it1, 20);
cout << *it2 << endl;

//(3) template <class InputIterator>
//    void insert(InputIterator first, InputIterator last);
it1 = s1.find(1);
it2 = s1.find(20);
set<int> s2;
s2.insert(it1, it2);

set<int>::iterator S2it = s2.begin();
while (S2it != s2.end()){
cout << *S2it << " ";
++S2it;
}
cout << endl;

//(1) iterator  erase(const_iterator position);
it1 = s1.find(1);
it2 = s1.erase(it1);
cout << *it2 << endl;

it1 = s1.find(20);
it2 = s1.erase(it1);
if (it2 == s1.end()){

cout << "迭代器指向空!" << endl;
}

//(2) size_type erase(const value_type& val);

cout << "删除元素个数:" << s1.erase(2) << endl;
cout << "删除元素个数:" << s1.erase(20) << endl;

//(3) iterator  erase(const_iterator first, const_iterator last);
//iterator lower_bound(const value_type& val);
it1 = s2.find(2);
it2 = s2.find(5);
s2.erase(it1, it2);

S2it = s2.begin();
while (S2it != s2.end()){
cout << *S2it << " ";
++S2it;
}
cout << endl;

set<int>::iterator S1it = s1.begin();
while (S1it != s1.end()){
cout << *S1it << " ";
++S1it;
}
cout << endl;
}


结果:



map:



插入:

//库中pair<_Ty1, _Ty2> make_pair(const _Ty1& _Val1, const _Ty2& _Val2);的类似结构
template<class _Ty1,class _Ty2>
pair<_Ty1, _Ty2> make_pair(const _Ty1& _Val1, const _Ty2& _Val2){
return pair<_Ty1, _Ty2>(_Val1, _Val2);
}

//类型 value_type 可看作pair<value_type,mapped_type>
//结点中存储的是键值对`pair<value_type,mapped_type>`: `key_type`为键值
//对第一个参数类型、`mapped_type` 为键值对第二个参数类型。


类似于
set
的插入。

//(1) pair<iterator, bool> insert(const value_type& val);


参数:
val
为要插入的元素。

返回值:返回键值对
pair<iterator, bool>
类型的的值。若集合中无
val
元素则插入成功,
first
为新插入元素的位置的迭代器,
second
true
,若集合中已有
val
元素则不插入元素,
first
为已存在元素的位置的迭代器,
second
false


//(2) iterator insert(const_iterator position, const value_type& val);


参数:
position
指定的迭代器位置,
val
position
指定的位置之前插入的元素,注意并不是一定在此位置插入,因为集合中的元素是有顺序的,随便插入会打乱元素顺序,所以可能改变插入的位置。

返回值:返回值指向在集合中新插入的元素或已经存在的具有相同值得元素的位置。

//(3) template <class InputIterator>


// void insert(InputIterator first, InputIterator last);


模板参数
InputIterator
为迭代器类型,此函数插入一个迭代器区间(左闭右开)的数据。

删除:

类似于
set
的插入。

//(1) iterator  erase(const_iterator position);


参数:
position
要删除位置的迭代器。

返回值:返回删除元素下一个元素的迭代器,若删除元素为最后一个元素则返回NULL迭代器。

//(2) size_type erase(const key_type& k);


该函数返回已删除
val
元素的个数,对于multiset版本的可以删除多个。

//(3) iterator  erase(const_iterator first, const_iterator last);


该函数删除一段迭代器区间,返回删除区间最后一个元素之后元素的迭代器。

修改:

注意:这个成员函数要特别留意。

//mapped_type& operator[] (key_type&& k);


随机访问时,以键值对第一个参数(k)为下标索引整个集合,若集合中存在结点第一个参数为
k
的元素 ,则返回与
k
对应的键值对的第二个值的引用,若不存在,则插入以
k
mapped_type
组成的键值对 ,并返回刚插入键值对第二个参数的引用。

验证:

#include<iostream>
using namespace std;

#include<map>
#include<string>

void TestMap(){

map<string, string> dic;

dic.insert(make_pair("English", "英语"));
dic.insert(make_pair("Math", "数学"));
dic.insert(make_pair("Chinese", "语文"));

//(1) pair<iterator, bool> insert(const value_type& val);

pair<map<string, string>::iterator, bool> ret = dic.insert(make_pair("sports", "体育"));
cout << "pair<>.first:" << (*ret.first).first << "  pair<>.second:"
<< (*ret.first).second << "  true/false:" << ret.second << endl;
ret = dic.insert(make_pair("sports", "体育"));

cout << "pair<>.first:" << (*ret.first).first << "  pair<>.second:"
<< (*ret.first).second << "  true/false:" << ret.second << endl;

//(3) template <class InputIterator>
//  void insert(InputIterator first, InputIterator last);

map<string, string> dic2;

map<string, string>::iterator it2 = dic.find("English");
map<string, string>::iterator it3 = dic.find("sports");

dic2.insert(it2, it3);

map<string, string>::iterator it = dic2.begin();
while (it != dic2.end()){
cout << (*it).first << ' ' << (*it).second << "   ";
++it;
}
cout << endl;
//(1) iterator  erase(const_iterator position);
it2 = dic.find("English");
dic.erase(it2);

it2 = dic.find("sports");
if (dic.erase(it2) == dic.end()){
cout << "返回为空的迭代器!" << endl;
}

//(2) size_type erase(const key_type& k);

cout << dic.erase("Math") << endl;

//(3) iterator  erase(const_iterator first, const_iterator last);

it2 = dic2.find("English");
it3 = dic2.find("Math");

dic2.erase(it2, it3);

it = dic2.begin();
while (it != dic2.end()){
cout << (*it).first << ' ' << (*it).second << "   ";
++it;
}
cout << endl;

//mapped_type& operator[] (key_type&& k);

cout <<" :>" << dic2["English"] << endl;
dic2["English"] = "英语";
cout << " :>" << dic2["English"] << endl;

it = dic2.begin();
while (it != dic2.end()){
cout << (*it).first << ' ' << (*it).second << "   ";
++it;
}
cout << endl;
it = dic.begin();
while (it != dic.end()){
cout << (*it).first << ' ' << (*it).second << "   ";
++it;
}

cout << endl;
}


结果:



总结:
map
set
的插入、删除、查找基本相同,这是因为它们的底层都封装的是’红黑树‘的原因,因为
set
中结点只含有
kay
不能随意修改(随意修改会破坏元素顺序),又因
operator[]
一般实现随机访问,所返回的元素可以被修改,所以
set
并没有实现
operator[]
,而
map
中不仅仅存储的是
kay
而是存储
kay
value
共同组成的键值对,所以可通过
operator[kay]
搜索到所对应的键值对并返回所对应的
value
的引用,进而修改所对应的
value
,另外,
operator[]
在访问时,若集合中没有要查找的元素,则插入并返回所对应默认的
value
值 的引用。若有,直接返回对应
value
值的引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: