一、使用关联容器
key---value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字;set支持高效的关键字查询操作---检查一个关键字是否在set中。
multimap允许多个元素具有相同的关键字。
pair类型用于保存两个数据类型,pair的数据成员是public的。
【Note】:
定义一个map时,必须指明关键字类型和值类型;而定义set时,只需指定关键字类型。
一个map或者set中的关键字是唯一的,并且得到的值是按字典序排列的。
map的value_type是一个pair,但是关键字是const类型。
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>//pair类型存在于该头文件中。
#include <string>
using namespace std;
using v_int = vector<int>;
using v_str = vector<string>;
pair<string,int> process(vector<string> &v);
int main(int argc, char const *argv[])
{
/*************************
*使用关联容器(map、set)。
**************************/
map<string,size_t> word_count;//空map,关键字是string,值是size_t类型。
set<string> exclude = {"the","but"};//用set保存想忽略的单词。
string word;
while(cin >> word)
{
//find返回一个迭代器,如果关键字在set中,迭代器指向该关键字,否则返回尾迭代器。
if(exclude.find(word) == exclude.end())//只统计不在exclude中的单词。
++word_count[word];//使用string作为下标,提取word的计数器并将其加一。
}
for (const auto &w : word_count)
{
//map使用的pair用first成员保存关键字,用second成员保存对应的值。
cout << w.first << " occurs " << w.second <<
((w.second > 1) ? " times" : " time") << endl;
}
v_int vec;
for (auto i=0 ; i!=10 ; ++i)
{
vec.push_back(i);
vec.push_back(i);
}
set<int> iset(vec.cbegin(),vec.cend());
multiset<int> miset(vec.cbegin(),vec.cend());//允许多个元素具有相同的初始值。
cout << vec.size() << endl;
cout << iset.size() << endl;
cout << miset.size() << endl;
/*****************************
*pair类型(保存两个数据类型)。
******************************/
string str;
int a;
vector<pair<string,int>> vec2;
while(cin >> str >> a)
{
pair<string,int> p = {str,a};
vec2.push_back(p);
}
for (const auto s : vec2)
{
cout << s.first << " " << s.second << endl;
}
v_str vstr = {"abc","ef"};
auto p2 = process(vstr);
cout << p2.first << " " << p2.second << " " << endl;
system("pause");
return 0;
}
pair<string,int> process(vector<string> &v)//创建pair对象的函数。
{
if(!v.empty())
{
//返回最后一个元素,并得到其长度。
return { v.back(),v.back().size() };//对返回值进行列表初始化。
}
else
{
return pair<string,int>();
}
}
上述代码的运行结果如下:
二、关联容器操作
1、关联容器操作(迭代器、遍历迭代器、insert、erase、下标操作、访问元素)
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <string>
using namespace std;
using v_int = vector<int>;
pair<string,int> process(vector<string> &v);
int main(int argc, char const *argv[])
{
/***************************
*关联容器迭代器、遍历迭代器。
****************************/
map<string,int> word_count =
{
{"ABC",1},
{"EDF",2}
};
//获得指向首元素的迭代器。
auto map_it = word_count.cbegin();
while(map_it != word_count.cend())
{
//解引用迭代器。
cout << map_it->first << " occurs " << map_it->second << " times" << endl;
++map_it;
}
/*******************
*添加元素(insert)。
********************/
map<string,size_t> word_count2;
string word;
while(cin >> word)
{
auto ret = word_count2.insert({word,1});
if(!ret.second)
++(ret.first->second);//ret是一个pair类型,其第一个成员是一个map迭代器。
}
for (const auto &w : word_count2)
{
cout << w.first << " occurs " << w.second << " time" << endl;
}
//向multimap或者multiset中添加元素。
multimap<string,string> authors;//一个关键字与多个元素相关联,比如一个作者出版的书。
authors.insert({"Eric","DSP"});
authors.insert({"Eric","convex"});
authors.insert({"Eric","matrix"});
for (const auto &w : authors)
{
cout << w.first << " " << w.second << endl;
}
/******************
*删除元素(erase)。
*******************/
string removal_word = {"EDF"};
if(word_count.erase(removal_word))//删除一个关键字返回删除的元素数量。
{
cout << removal_word << " removed!" << endl;
}
else
{
cout << removal_word << " not found!" << endl;
}
for (const auto &w : word_count)
{
cout << w.first << " occurs " << w.second <<
((w.second > 1) ? " times" : " time") << endl;
}
/**************
*map的下标操作。
***************/
word_count["EDF"] = 1;//插入一个关键字,并进行值初始化,如果是新的关键字就添加到map中。
++word_count["EDF"];//返回值是一个左值,可读可写。
cout << word_count["EDF"] << endl;
/******************
*访问元素(find、count、lower_bound、upper_bound)。
*******************/
set<int> iset = {1,4,5,6,7,8,9};
iset.find(1);
cout << iset.count(1) << endl;
string search_author("Eric");//要查找的作者。
auto entries = authors.count(search_author);//元素的数量。
auto iter = authors.find(search_author);//此作者的第一本书。
while(entries)
{
cout << iter->second << " ";//打印每个书名。
++iter;
--entries;
}
cout << endl;
//lower_bound定位到第一个匹配的元素,upper_bound指向最后一个匹配的元素,如果两者相等,则无关键字。
for (auto beg = authors.lower_bound(search_author),
end = authors.upper_bound(search_author) ;
beg != end ; ++beg)
{
cout << beg->second << " ";
}
cout << endl;
for (auto pos = authors.equal_range(search_author) ;
pos.first != pos.second ; ++pos.first)
{
cout << pos.first->second << " ";
}
system("pause");
return 0;
}
上述代码的运行结果如下:
三、一个应用关联容器的demo
一个单词转换的map:给定一个string,按某种规则转换为另一个string,转换规则是用某些字母替换对应的短语。
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <sstream>
using namespace std;
void word_transform(ifstream &map_file,ifstream &input,ofstream &out);
map<string,string> BuildMap(ifstream &map_file);
const string &transform(const string &s,const map<string,string> &m);
int main(int argc, char const *argv[])
{
ifstream in("input.txt");
ifstream trans("trans.txt");
ofstream out("output.txt");
word_transform(trans,in,out);
system("pause");
return 0;
}
//子函数输出到文件中,添加一个引用类型的参数即可。
void word_transform(ifstream &map_file,ifstream &input,ofstream &out)
{
auto trans_map = BuildMap(map_file);//保存转换规则。
string text;
while(getline(input,text))//读取每一行输入。
{
istringstream stream(text);//string流输入。
string word;
bool firstword = true;
while(stream >> word)//读取输入的每个单词。
{
if(firstword)
{
firstword = false;//控制是否打印空格。
}
else
{
out << " ";//打印单词间的一个空格。
}
out << transform(word,trans_map);//打印输出。
}
out << endl;
}
}
map<string,string> BuildMap(ifstream &map_file)
{
map<string,string> trans_map;
string key;
string value;
//读取第一个单词存入key,剩余内容放在value中。
while(map_file >> key && getline(map_file,value))
{
if(value.size() > 1)//检查是否有转换规则。
{
trans_map[key] = value.substr(1);//跳过前导的空格
}
else
{
throw runtime_error("no rule for" + key);
}
}
return trans_map;
}
const string &transform(const string &s,const map<string,string> &m)
{
auto map_it = m.find(s);//实际的转换规则。
if(map_it != m.cend())//如果单词在转换规则中。
{
return map_it->second;//使用替换短语。
}
else
{
return s;//没有就返回原来的string。
}
}
上述代码的运行结果如下:
四、无序容器
unordered_map是无序容器,关键字类型是无序的,使用hash函数和关键字类型的==运算符。
#include <iostream>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;
int main(int argc, char const *argv[])
{
//unordered_map是无序容器,关键字类型是无序的,使用hash函数和关键字类型的==运算符。
unordered_map<string,size_t> word_count;
string word;
while(cin >> word)
{
++word_count[word];
}
for (const auto &w : word_count)
{
cout << w.first << " occurs " << w.second <<
((w.second > 1) ? " times" : " time") << endl;
}
system("pause");
}
标签:map,multimap,word,string,关键字,set,const,include
From: https://blog.51cto.com/u_6526235/7788101