使用map对象,则需要包含map头文件。在定义map对象时,必须分别指明键和值的类型。
一、map对象的定义
map的构造函数如下:
构造函数
|
说明
|
map<k, v> m;
|
创建一个名为m的空map对象,其键和值的类型分别为k和v。
|
map<k, v> m(m2);
| 创建m2的副本m,m与m2必须有相同的键类型和值类型。 |
map<k, v> m(b, e);
|
创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本。元素的类型必须能转换为pair<const k, v>。
|
二、map定义的类型
map类类型成员
| 说明 |
map<K, V>::key_type
| 在map容器中,用作索引的键的类型。 |
map<K, V>::mapped_type
|
在map容器中,键所关联的值的类型。
|
map<K, V>::value_type
|
一个
pair类型,它的first元素具有
const map<K, V>::key_type类型,而second元素则为map<K, V>::mapped_type类型。
|
注:map迭代器返回value_type类型的值,而下标操作符返回一个mapped_type类型的值。
三、map对象插入元素
插入方法
|
说明
|
m.insert(e)
|
e是map类型对应的value_type类型的值。如果键(e.first)不在m中,则插入一个值为e.second的新元素;如果键(e.first)在m中已存在,则保持m不变。该函数返回一个pair类型的对象,包含指向键为e.first元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素。
|
m.insert(beg, end)
|
beg和end是标记元素范围的迭代器,其中的元素必须为m.value_type类型的键-值对。对于这些元素,如果其键在m中不存在,则将该键对应的元素插入m。返回值为void。
|
m.insert(iter, e)
|
e是map类型对应的value_type类型的值。如果(e.first)不在m中,则插入一个值为e.second的新元素,并以迭代器iter为起点搜索新元素存储的位置。该函数返回一个迭代器,指向m中具有给定键的元素。
|
四、map元素的查找和访问
查询方法
|
说明
|
m.count(k)
|
返回m中k的出现次数。返回值只能是0或者1,因为map容器只允许一个键对应一个实例。
|
m.find(k)
|
如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。
|
五、map元素的删除
删除方法
|
说明
|
m.erase(k)
|
删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数。
|
m.
erase(p)
|
从m中删除迭代器p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m.end()。返回void类型。
|
m.
erase
(b, e)
|
从m中删除一段范围内的元素,b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出现在e所指向的元素之前。返回void类型。
|
六、map容器的遍历
使用迭代器进行遍历,如:map<string, int>::const_iterator map_it = word_count.begin();
注:在使用迭代器遍历map容器时,迭代器指向的元素按键的升序排列。
习题10.9:统计单词出现的次数
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
using namespace std;
int main()
{
map<string, int> word_count;
string word;
cout << "Enter some words(Ctrl + Z or Ctrl + D to end):" << endl;
while (cin >> word)
{
++word_count[word];
}
cout << "word\t\t" << "times" << endl;
for (map<string, int>::iterator it = word_count.begin(); it != word_count.end(); ++it)
{
cout << it->first << "\t\t" << it->second << endl;
}
return 0;
}
[chapter10]$ ./a.out
Enter some words(Ctrl + Z or Ctrl + D to end):
abc abc ab def
word times
ab 1
abc 2
def 1
习题10.12:统计单词出现的次数(insert函数实现)
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
using namespace std;
int main()
{
map<string, int> word_count;
string word;
cout << "Enter some words(Ctrl + Z or Ctrl + D to end):" << endl;
while (cin >> word)
{
pair<map<string, int>::iterator, bool> ret = word_count.insert(pair<string, int>(word, 0));
++ret.first->second;
}
cout << "Word\t\t" << "times" << endl;
for (map<string, int>::iterator it = word_count.begin(); it != word_count.end(); ++it)
{
cout << it->first << "\t\t" << it->second << endl;
}
return 0;
}
[chapter10]$ ./a.out
Enter some words(Ctrl + Z or Ctrl + D to end):
aaa bbb ccc ddd aaa bbb ccc eee
Word times
aaa 2
bbb 2
ccc 2
ddd 1
eee 1
习题10.17:单词转换
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <stdexcept>
using namespace std;
ifstream & open_file(ifstream &in, const string &file)
{
in.close();
in.clear();
in.open(file.c_str());
return in;
}
int main(int argc, char **argv)
{
map<string, string> trans_map;
string key, value;
if (argc != 3)
{
throw runtime_error("wrong number of arguments");
}
ifstream map_file;
if (!open_file(map_file, argv[1]))
{
throw runtime_error("no transformation file");
}
while (map_file >> key >> value)
{
trans_map.insert(make_pair(key, value));
}
ifstream input;
if (!open_file(input, argv[2]))
{
throw runtime_error("no input file");
}
string line;
while (getline(input, line))
{
istringstream stream(line);
string word;
bool firstword = true;
while (stream >> word)
{
map<string, string>::const_iterator map_it = trans_map.find(word);
if (map_it != trans_map.end())
{
word = map_it->second;
}
if (firstword)
{
firstword = false;
}
else
{
cout << " ";
}
cout << word;
}
cout << endl;
}
return 0;
}
[chapter10]$ ./a.out
terminate called after throwing an instance of 'std::runtime_error'
what(): wrong number of arguments
Aborted (core dumped)
[chapter10]$ ./a.out dic daa
terminate called after throwing an instance of 'std::runtime_error'
what(): no transformation file
Aborted (core dumped)
[chapter10]$ ./a.out dict.txt aaa
terminate called after throwing an instance of 'std::runtime_error'
what(): no input file
Aborted (core dumped)
[chapter10]$ cat dict.txt
i I
love LOVE
you YOU
[chapter10]$ cat input.txt
i love you
i love you
[chapter10]$ ./a.out dict.txt input.txt
I LOVE YOU
I LOVE YOU
习题10.18:姓氏名字
[chapter10]$ cat exercise_10.18_name.cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
int main()
{
map<string, vector<string> > children;
string surname, childname;
// Read: Surname + childname1 + childname2 + ... + childnamen
do
{
cout << "Enter surname(Ctrl + Z or Ctrl + D to end):" << endl;
cin >> surname;
if (!cin)
{
break;
}
vector<string> chd;
pair<map<string, vector<string> >::iterator, bool> ret = children.insert(make_pair(surname, chd));
if (!ret.second)
{
cout << "repeated surname: " << surname << endl;
continue;
}
cout << "Enter children's name(Ctrl + Z or Ctrl + D to end):" << endl;
while (cin >> childname)
{
ret.first->second.push_back(childname);
}
cin.clear();
} while(cin);
cin.clear();
cout << "Enter a surname to search:" << endl;
cin >> surname;
map<string, vector<string> >::iterator iter = children.find(surname);
if (iter == children.end())
{
cout << "no this surname: " << surname << endl;
}
else
{
cout << "children: " << endl;
vector<string>::iterator it = iter->second.begin();
while (it != iter->second.end())
{
cout << *it++ << endl;
}
}
return 0;
}
[chapter10]$ ./a.out
Enter surname(Ctrl + Z or Ctrl + D to end):
123
Enter children's name(Ctrl + Z or Ctrl + D to end):
a b c d e f g
Enter surname(Ctrl + Z or Ctrl + D to end):
Enter a surname to search:
123
children:
a
b
c
d
e
f
g
习题10.19:姓氏名字生日
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
int main()
{
map<string, vector<pair<string, string> > > children;
string surname, childname, birthday;
// Read: Surname + childname1&birthday1 + childname2&birthday2 + ... + childnamen&birthdayn
do
{
cout << "Enter surname(Ctrl + Z or Ctrl + D to end):" << endl;
cin >> surname;
if (!cin)
{
break;
}
// child's name and birthday
vector<pair<string, string> > chd;
pair<map<string, vector<pair<string, string> > >::iterator, bool> ret = children.insert(make_pair(surname, chd));
if (!ret.second)
{
cout << "repeated surname: " << surname << endl;
continue;
}
cout << "Enter children's name and birthday(Ctrl + Z or Ctrl + D to end):" << endl;
while (cin >> childname >> birthday)
{
ret.first->second.push_back(make_pair(childname, birthday));
}
cin.clear();
} while(cin);
cin.clear();
while (1)
{
cout << "Enter a surname to search:" << endl;
cin >> surname;
map<string, vector<pair<string, string> > >::iterator iter = children.find(surname);
if (iter == children.end())
{
cout << "no this surname: " << surname << endl;
}
else
{
cout << "children\t\tbirthday" << endl;
vector<pair<string, string> >::iterator it = iter->second.begin();
while (it != iter->second.end())
{
cout << it->first << "\t\t" << it->second << endl;
it++;
}
}
}
return 0;
}
[chapter10]$ ./a.out
Enter surname(Ctrl + Z or Ctrl + D to end):
123
Enter children's name and birthday(Ctrl + Z or Ctrl + D to end):
a 11111111 b 22222222
Enter surname(Ctrl + Z or Ctrl + D to end):
Enter a surname to search:
123
children birthday
a 11111111
b 22222222
Enter a surname to search:
456
no this surname: 456
Enter a surname to search:
^C