您的位置:首页 > 编程语言 > C语言/C++

关联数组map和关联容器set的用法和二者的区别

2013-05-11 11:41 281 查看
map(也叫关联数组):

       map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
 
1. map的构造函数
map<int,string> maphai;
map<char,int> maphai;
map<string,char> mapstring;
map<string,int> mapstring;
map<int,char>mapint;
map<char,string>mapchar;
 
2. 数据的插入
在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:
第一种:用insert函数插入pair数据,
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent.insert(pair<int,string>(1,“student_one”));
mapStudent.insert(pair<int,string>(2,“student_two”));
mapStudent.insert(pair<int,string>(3,“student_three”));
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
 
第二种:用insert函数插入value_type数据,下面举例说明
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent.insert(map<int,string>::value_type (1,“student_one”));
mapStudent.insert(map<int,string>::value_type (2,“student_two”));
mapStudent.insert(map<int,string>::value_type (3,“student_three”));
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
 
第三种:用数组方式插入数据,下面举例说明
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent[1] = “student_one”;
mapStudent[2] = “student_two”;
mapStudent[3] = “student_three”;
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
       以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值,用程序说明
      mapStudent.insert(map<int,string>::value_type (1,“student_one”));
      mapStudent.insert(map<int,string>::value_type (1,“student_two”));
      上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下
      pair<map<int,string>::iterator,bool> Insert_Pair;
      Insert_Pair = mapStudent.insert(map<int,string>::value_type (1,“student_one”));
      我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。
 
下面给出完成代码,演示插入成功与否问题
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
Pair<map<int,string>::iterator,bool> Insert_Pair;
Insert_Pair = mapStudent.insert(pair<int,string>(1,“student_one”));
If(Insert_Pair.second == true)
{
Cout<<”Insert Successfully”<<endl;
}
Else
{
Cout<<”Insert Failure”<<endl;
}
Insert_Pair = mapStudent.insert(pair<int,string>(1,“student_two”));
If(Insert_Pair.second == true)
{
Cout<<”Insert Successfully”<<endl;
}
Else
{
Cout<<”Insert Failure”<<endl;
}
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
大家可以用如下程序,看下用数组插入在数据覆盖上的效果
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent[1] = “student_one”;
mapStudent[1] = “student_two”;
mapStudent[2] = “student_three”;
map<int,string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
3. map的大小
在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:
Int nSize = mapStudent.size();
4. 数据的遍历
这里也提供三种方法,对map进行遍历
第一种:应用前向迭代器,上面举例程序中到处都是了,略过不表
第二种:应用反相迭代器,下面举例说明,要体会效果,请自个动手运行程序
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent.insert(pair<int,string>(1,“student_one”));
mapStudent.insert(pair<int,string>(2,“student_two”));
mapStudent.insert(pair<int,string>(3,“student_three”));
map<int,string>::reverse_iterator iter;
for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
{
Cout<<iter->first<<” ”<<iter->second<<end;
}
}
第三种:用数组方式,程序说明如下
#include <map>
#include <string>
#include <iostream>
Using namespace std;
Int main()
{
Map<int,string> mapStudent;
mapStudent.insert(pair<int,string>(1,“student_one”));
mapStudent.insert(pair<int,string>(2,“student_two”));
mapStudent.insert(pair<int,string>(3,“student_three”));
int nSize = mapStudent.size()
//此处有误,应该是 for(int nIndex = 1; nIndex <= nSize; nIndex++)

//by rainfish
for(int nIndex = 0; nIndex < nSize; nIndex++)
{
Cout<<mapStudent[nIndex]<<end;
}
}
 
set关联容器:

set是C++标准库中的一种关联容器。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。

set容器的每一个键只能对应一个元素,即不存在键相同的不同元素。
示例代码:
#include <iostream>
#include <set>
#include <vector>
int main(int argc, char* argv[]) {
std::vector<int>vec;
for(std::vector<int>::size_type i = 0; i < 10; ++i) {
vec.push_back(i);
vec.push_back(i);
}
std::cout<< "vector : " << std::endl;
for(std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout<< *it << ",";
}
std::cout<< std::endl;
std::set<int>st(vec.begin(), vec.end());
std::cout<< "set : " << std::endl;
for(std::set<int>::iterator it = st.begin(); it != st.end(); ++it) {
std::cout<< *it << ",";
}
std::cout<< std::endl;
return 0;
}
输出结果:
vector :
0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9
set :
0,1,2,3,4,5,6,7,8,9
创建了一个int型的vector容器,存储20个数据,0~9每个数字都出现了两次。用整个vector初始化一个int型set容器,这个set容器却只有10个元素,0~9每个数字只出现一次。证实了set容器的每一个键只能对应一个元素。

编辑本段添加元素

可以使用insert操作向set容器添加元素。
示例代码:
#include <iostream>
#include <set>
#include <vector>
int main(int argc, char* argv[]) {
std::vector<int>vec;
vec.push_back(1);
vec.push_back(2);
std::set<int>st;
st.insert(10);
st.insert(vec.begin(),vec.end());
std::cout<< "set : ";
for(std::set<int>::iterator it = st.begin(); it != st.end(); ++it) {
std::cout<< *it << " ";
}
std::cout<< std::endl;
return 0;
}
输出结果:
set : 1 2 10
insert()的参数既可以是一个键,也可以是一对迭代器,它们都可以实现向set容器中添加元素,只不过函数的返回值不同。另外,可以看出向set容器中添加元素后,它会自动排序。

编辑本段获取元素

与map容器不同,set容器不支持下标操作访问元素。
使用count()函数可以查询元素是否存在,如果查询的元素存在则返回1,反之则0。使用find()函数,如果查询的元素存在则返回指向该元素的迭代器,反之则返回超出末端迭代器
示例代码:
#include <iostream>
#include <set>
int main(int argc, char* argv[]) {
std::set<int> st;
st.insert(1);
st.insert(5);
st.insert(10);
std::cout<< "count(5) : " << st.count(5) << std::endl;
std::cout<< "find(5): " << *st.find(5) << std::endl;
return 0;
}
输出结果:
count(5) : 1
find(5): 5
使用count()和find()函数查询同一元素5,count()函数返回的是该元素在set容器中的数量,find()函数则返回指向该元素的迭代器。需要注意的是,虽然使用find()函数可以返回指向该元素的迭代器,但只能对其做读操作,任何试图修改键值的操作都是非法的。
 
二者的区别:
1、map容器是键/值对的集合,与map关联容器不同,set它只是单纯键的集合。
2、map容器支持下标操作符访问元素,map容器不同,set容器不支持下标操作访问元素。
 
参考网址:
http://baike.baidu.com/view/95826.htm#sub8050590
http://baike.baidu.com/view/10312991.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ map set