map ,set属于STL里的组件,叫做标准关联容器。
标准关联容器的典型实现是平衡二叉查找树。一个平衡二叉查找树是一个对插入、删除和查找的混合操作优化的数据结构。换句话说,它被设计为应用于进行一些插入,然后一些查找,然后可能再进行一些插入,然后也许一些删除,然后再来一些查找,然后更多的插入或删除,然后更多的查找等。这个事件序列的关键特征是插入、删除和查找都是混合在一起的。一般来说,没有办法预测对树的下一个操作是什么。
在很多应用中,使用数据结构并没有那么混乱。它们对数据结构的使用可以总结为这样的三个截然不同的阶段:
1. 建立。通过插入很多元素建立一个新的数据结构。在这个阶段,几乎所有的操作都是插入和删除。几乎没有或根本没有查找。
2. 查找。在数据结构中查找指定的信息片。在这个阶段,几乎所有的操作都是查找。几乎没有或根本没有插入和删除。
3. 重组。修改数据结构的内容,也许通过删除所有现有数据和在原地插入新数据。从动作上说,这个阶段等价于阶段1。一旦这个阶段完成,应用程序返回阶段2。
而map和set正是通过这样的方式来实现增删查改。map和set里又包含multimap,multiset。它们两个属于多重集,因为平衡二叉查找树里面是不允许有重复的值,那么我们还是想要插入已经含有的值怎么办?那么就可以使用多重集来进行操作。
map:
是K&V模型,但是通常只能返回一个参数,所以用pair进行封装,pair实质上是个结构体,封装了key和value,作为first和second,访问时可以通过迭代器进行访问这两个成员,那么first就是那个key,second事实上可以作为一个计数器进行使用,当使用map作为字典时,value可以是对前面key的解释。
map使用:
//map不包含重复的值
void test_map()
{
//插入int型的值
/*map<int, int> m;
m.insert(pair<int,int>(2, 3));
m.insert(pair<int, int>(3, 3));
m.insert(pair<int, int>(4, 3));
m.insert(pair<int, int>(5, 3));
m.insert(pair<int, int>(6, 3));
map<int, int>::iterator it = m.begin();
while (it!=m.end())
{
cout << (*it).first <<" "<<(*it).second<< endl;
it++;
}*/
//插入字符串型的值
//map<string, string> m1;
//m1.insert(pair<string, string>("sort", "排序"));
//m1.insert(pair<string, string>("insert", "插入"));
//m1.insert(pair<string, string>("hehe", "呵呵哒"));
//m1.insert(pair<string, string>("xixi", "嘻嘻"));
//map<string, string>::iterator it1 = m1.begin();
//while (it1 != m1.end())
//{
// //printf("%s , %s\n",it1->first , (*it1).second );
// cout << (*it1).first <<" " <<(*it1).second << endl;
// //cout << it1->first <<" "<< it1->second << endl;
// it1++;
//}
//cout << endl;
//find()找这个位置是否存在-----erase()删除这个位置
//map<string, string>::iterator pos = m1.find("hehe");
//pos->second = "呵呵";
//if (pos != m1.end())
// m1.erase(pos);
//it1 = m1.begin();
//while (it1 != m1.end())
//{
// cout << (*it1).first << " " << (*it1).second << endl;
// it1++;
//}
//second可以作为计数器统计次数的出现
/*string str[] = { "sort", "sort", "second", "sort", "first", "first" };
map<string, size_t> countMap;
for (size_t i = 0; i < sizeof(str) / sizeof(str[0]); i++)
{*/
//第一种统计
//map<string, size_t>::iterator it = countMap.find(str[i]);
//if (it != countMap.end()){
// it->second++;
//}
//else{
// //make_pair实质上就是pair<string,size_t>,简写而已,
// countMap.insert(pair<string, size_t>(str[i], 1));
// countMap.insert(make_pair(str[i], 1));
//}
//第二种统计 第二个参数是bool型,如果出现返回false,没出现返回true
/*pair<map<string, size_t>::iterator, bool> ret= countMap.insert(make_pair(str[i],1));
if (ret.second == false)
{
ret.first->second++;
}*/
//第三种统计使用operator[]
/* countMap[str[i]]++;
}
map<string, size_t>::iterator it = countMap.begin();
while (it != countMap.end()){
cout << it->first << " " << it->second << endl;
it++;
}*/
//operator[]--------->[]的重载
//检查键k是否已经在map里。如果不,就添加上,以v作为它的对应值。如果k已经在map里,它的关联值被更新成v。
map<string, string> m;
m["insert"] = "插入";
m["hehe"] = "呵呵";
m["lala"] = "啦啦";
m["history"] = "历史";
m["lala"] = "拉拉";
map<string, string>::iterator it1 = m.begin();
while (it1 != m.end())
{
cout<<it1->first<<" : "<<it1->second<<endl;
++it1;
}
cout<<endl;
}
multimap的使用:(与map 不同的是可以有重复的值)
//多重集,包含重复的值
void test_multimap()
{
multimap<string, string> m;
m.insert(pair<string, string>("sdjf", "sjdfl"));
m.insert(pair<string, string>("sdjf", "sjdfl"));
m.insert(pair<string, string>("sdjf", "sjdfl"));
m.insert(pair<string, string>("sdjf", "sjdfl"));
multimap<string, string>::iterator it = m.begin();
while (it != m.end())
{
cout << it->first << " " << it->second << endl;
it++;
}
}
set :
K模型,直接访问key即可
set使用:
void test_set()
{
set<int> s;
s.insert(3);
s.insert(4);
s.insert(5);
s.insert(2);
s.insert(1);
set<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
it++;
}
}
multiset使用:
//多重集,包含重复的值
void test_multiset()
{
multiset<int> s;
s.insert(3);
s.insert(3);
s.insert(5);
s.insert(2);
s.insert(1);
multiset<int>::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
it++;
}
}