C++ map
最后修改于 2023 年 1 月 9 日
C++ map教程展示了如何在C++中操作map容器。
map是一个存储键/值对的容器。在其他编程语言中,map被称为关联容器、字典或哈希表。
map中的值通过其键来引用,而不是通过其在容器中的绝对位置。map中的键是唯一的。
C++ map简单示例
下面的示例展示了一些map的简单操作。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
cout << stones.size() << endl;
stones.insert({6, "spinel"});
cout << stones.size() << endl;
for (const auto& stone: stones) {
cout << stone.first << ": " << stone.second << endl;
}
stones.clear();
cout << stones.size() << endl;
}
我们定义了一个stones map。
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
在stones map中,键是整数,值是字符串。
cout << stones.size() << endl;
我们使用size方法获取map的大小。
stones.insert({6, "spinel"});
使用insert方法插入一个新的stone。
for (const auto& stone: stones) {
cout << stone.first << ": " << stone.second << endl;
}
我们使用for-range循环遍历map。
stones.clear();
使用clear移除所有键值对。
$ ./simple 5 6 1: citrine 2: garnet 3: topaz 4: opal 5: ametyst 6: spinel 0
C++ map访问元素
可以通过[]运算符或at方法,使用键来访问值。访问不存在的键会抛出异常。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
cout << stones.at(1) << endl;
cout << stones[4] << endl;
}
我们使用[]和at方法访问stones map中的两个值。
$ ./access citrine opal
C++ map更新元素
下面的示例演示了更新值。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> words {
{1, "sky"},
{2, "blue"},
{3, "cup"},
{4, "nice"},
};
words[1] = "skylark";
words.at(2) = "blues";
for (const auto &word : words) {
cout << "[" << word.first << ", " << word.second << "]" << endl;
}
}
我们使用赋值运算符更新map中两个键值对的值。
$ ./updating [1, skylark] [2, blues] [3, cup] [4, nice]
C++ map删除元素
使用erase方法从map中删除一个元素。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
stones.erase(4);
for (const auto& stone: stones) {
cout << stone.first << ": " << stone.second << endl;
}
}
我们删除键为4的键值对。
$ ./erasing 1: citrine 2: garnet 3: topaz 5: ametyst
C++ map erase_if
erase_if方法删除所有满足给定谓词返回true的元素。该方法在C++20中引入。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> words {
{1, "sky"},
{2, "blue"},
{3, "cup"},
{4, "nice"},
{5, "tall"},
{6, "car"},
{7, "top"}
};
erase_if(words, [](const auto& e) {
return (e.second.size() == 3);
});
for (const auto &word : words) {
cout << "[" << word.first << ", " << word.second << "]" << endl;
}
}
在这个例子中,我们从map中删除了所有长度为三个字符的单词。
$ clang++ erase_if.cpp -o erase_if -std=c++20 $ ./erase_if [2, blue] [4, nice] [5, tall]
C++ map merge
merge方法合并两个map。该方法在C++20中引入。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main() {
map<int, string> words {
{1, "sky"},
{2, "blue"},
{3, "cup"}
};
map<int, string> words2 {
{4, "nice"},
{5, "tall"},
{6, "car"},
{7, "top"}
};
words.merge(words2);
for (const auto &word : words) {
cout << "[" << word.first << ", " << word.second << "]" << endl;
}
}
我们合并了两个单词map。
$ ./merging [1, sky] [2, blue] [3, cup] [4, nice] [5, tall] [6, car] [7, top]
C++ map contains
contains方法检查是否存在具有指定键的元素。
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::endl;
using std::cout;
int main()
{
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
for (int x: {2, 3, 7}) {
if (stones.contains(x)) {
cout << x << ": found" << endl;
} else {
cout << x << ": not found" << endl;
}
}
}
contains方法在C++20中引入。
$ clang++ contains.cpp -o contains -std=c++20 $ ./contains 2: found 3: found 7: not found
C++ map使用while循环遍历
下面的示例使用while循环遍历map。
#include <iostream>
#include <map>
using std::cout;
using std::endl;
using std::string;
using std::map;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
auto it = stones.cbegin();
while (it != stones.cend()) {
cout << "[" << it->first << ", "
<< it->second << "]\n";
it++;
}
cout << endl;
return 0;
}
cbegin返回指向map开头的const迭代器,cend返回指向map末尾的const迭代器。
$ ./while_loop [1, citrine] [2, garnet] [3, topaz] [4, opal] [5, ametyst]
C++ map使用经典for循环遍历
下面的示例使用经典的for循环形式遍历map。
#include <iostream>
#include <map>
using std::cout;
using std::endl;
using std::string;
using std::map;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
for (auto it = stones.cbegin(); it != stones.cend(); it++) {
cout << "[" << it->first << ", "
<< it->second << "]"
<< endl;
}
cout << endl;
return 0;
}
我们使用经典的for循环遍历map中的stones。
C++ map使用for-range循环遍历
下面的示例使用for-range循环遍历map元素。
#include <iostream>
#include <map>
using std::cout;
using std::endl;
using std::string;
using std::map;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
for (const auto &stone : stones) {
cout << "[" << stone.first << ", " << stone.second << "]\n";
}
cout << endl;
return 0;
}
For-range循环在C++11中引入。
下一个示例展示了另一种for-range形式。
#include <iostream>
#include <map>
using std::cout;
using std::endl;
using std::string;
using std::map;
int main() {
map<int, string> stones {
{1, "citrine"},
{2, "garnet"},
{3, "topaz"},
{4, "opal"},
{5, "ametyst"}
};
// decomposition C++17
for (const auto& [key, value] : stones) {
cout << "[" << key << ", " << value << "]\n";
}
cout << endl;
return 0;
}
本例中使用的解构操作在C++17中引入。
在本文中,我们学习了如何在C++中操作map容器。