C++中的无序映射
在本文中,我们将介绍如何在C++中使用无序映射数据结构。
这是C++标准模板库(STL)的一部分,并且是非常有用的数据结构。
让我们使用一些说明性示例更详细地了解这一点。
无序映射数据结构
这是一个关联容器,可以将元素存储为键值对。
其中您将键与映射值相关联。
我们可以通过此键访问此映射值。
使用此数据结构的优势是由于其插入和删除时间非常快(平均O(1)时间复杂度)。
由于无序地图使用哈希表,因此将直接为我们提供非常快速的访问时间!
现在,我们使用一些说明性示例来理解这一点。
在C++ STL中使用无序映射
这是C++中STL的一部分,在 <unordered_map>
中定义。
#include <unordered_map> template <class Key, class Value> class unordered_map;
最常见的参数是"键"和"值",这是键值对。
您还可以将其他参数传递给std :: unordered_map
,但是为了说明起见,我们将不再使用它们。
(您可以在这里参考它们)
现在开始吧!
C++ STL中的无序映射–一些示例
让我们看一些C++中无序映射的示例。
1.插入到无序地图
首先,通过将其分配给变量来声明我们的容器结构。
#include <iostream> #include <unordered_map> #include <string> int main() { //We declare our unordered map (int, string) //Here, the key is an int, and the value is a string std::unordered_map<int, std::string> my_map; //Direct array-like access! my_map[10] = "Hello from theitroad!"; my_map[20] = "Sample String"; std::cout << my_map[10] << std::endl; std::cout << my_map[20] << std::endl; return 0; }
请注意,此数组与数组之间的相似之处在于分配和访问的方式相同!
输出
Hello from theitroad! Sample String
使用类似数组的索引进行分配和修改看起来非常容易。
现在,我们要遍历无序地图。
根据定义,由于无序映射不定义任何顺序,因此我们不能保证元素按顺序打印。
请记住,这是一个哈希表。
因此,这些值将基于其哈希值插入一个随机位置。
2.搜索无序地图
由于这是STL的一部分,因此我们可以使用迭代器对其进行迭代。
如果要搜索整个地图,可以直接使用" for-each"循环。
#include <iostream> #include <unordered_map> #include <string> int main() { //We declare our unordered map (int, string) //Here, the key is an int, and the value is a string std::unordered_map<int, std::string> my_map; //Directly array-like access! my_map[10] = "Hello from theitroad!"; my_map[20] = "Sample String"; //We can traverse using a for-each loop for (const auto& it: my_map) { //Here, it.first -> Key //and it.seconds -> Value std::cout << it.first << ": " << it.second << std::endl; } return 0; }
输出
20: Sample String 10: Hello from theitroad!
请注意,在我的情况下,不保留搜索顺序。
这确实表明地图是无序的。
如果要查找特定键是否存在,可以使用" find"方法进行元素查找。
#include <iostream> #include <unordered_map> #include <string> int main() { //We declare our unordered map (int, string) //Here, the key is an int, and the value is a string std::unordered_map<int, std::string> my_map; //Directly array-like access! my_map[10] = "Hello from theitroad!"; my_map[20] = "Sample String"; std::cout << "Searching for element with key = 10\n"; auto it = my_map.find(10); std::cout << it->first << ": " << it->second << std::endl; std::cout << "Searching for element with key = 30\n"; it = my_map.find(30); std::cout << it->first << ": " << it->second << std::endl; return 0; }
输出
Searching for element with key = 10 10: Hello from theitroad! Searching for element with key = 30 [1] 243 segmentation fault (core dumped) ./a.out
虽然我们可以在第一种情况下获得键值对(10),但在第二种情况下发生了什么?
由于在地图中找不到键30,因此迭代器没有"第一"或者"第二"成员。
为避免这种情况,我们必须检查密钥是否不存在。
如果密钥不存在,我们将获得特殊的迭代器" std :: unordered_map.end()"。
让我们为搜索添加过滤条件。
#include <iostream> #include <unordered_map> #include <string> int main() { //We declare our unordered map (int, string) //Here, the key is an int, and the value is a string std::unordered_map<int, std::string> my_map; //Directly array-like access! my_map[10] = "Hello from theitroad!"; my_map[20] = "Sample String"; std::cout << "Searching for element with key = 10\n"; auto it = my_map.find(10); if (it != my_map.end()) std::cout << it->first << ": " << it->second << std::endl; else std::cout << "Key not found\n"; std::cout << "Searching for element with key = 30\n"; it = my_map.find(30); if (it != my_map.end()) std::cout << it->first << ": " << it->second << std::endl; else std::cout << "Key not found\n"; return 0; }
输出
Searching for element with key = 10 10: Hello from theitroad! Searching for element with key = 30 Key not found
现在,只要在地图上找不到键,我们就可以正确指出。
3.从无序地图中删除
与插入和搜索类似,我们还可以从无序映射中删除元素。
STL为我们提供了" erase()"方法。
我们可以通过多种方式擦除元素:
- 使用迭代器(
my_map.erase(mymap.begin())
) - 使用密钥(
my_map.erase(key)
) - 通过范围(`my_map.erase(my_map.find(key),my_map.end()))
第一种方法将删除第一个索引处的元素(如果存在)。
第二种方法将从映射中删除键值对(如果存在)。
第三种方法将使用基于范围的迭代器来擦除它们之间的所有元素!
#include <iostream> #include <unordered_map> #include <string> int main() { //We declare our unordered map (int, string) //Here, the key is an int, and the value is a string std::unordered_map<int, std::string> my_map; //Directly array-like access! my_map[10] = "Hello from theitroad!"; my_map[20] = "Sample String"; my_map[30] = "Text"; std::cout << "Initially, map contains:\n"; for (const auto& it: my_map) { std::cout << it.first << ": " << it.second << std::endl; } std::cout << "Deleting Key: 10...\n"; my_map.erase(10); std::cout << "Map now contains:\n"; for (const auto& it: my_map) { std::cout << it.first << ": " << it.second << std::endl; } //Erase everything! From beginning to the end my_map.erase(my_map.begin(), my_map.end()); std::cout << "Map now contains:\n"; for (const auto& it: my_map) { std::cout << it.first << ": " << it.second << std::endl; } return 0; }
输出
Initially, map contains: 30: Text 20: Sample String 10: Hello from theitroad! Deleting Key: 10... Map now contains: 30: Text 20: Sample String Map now contains:
如您所见,我们能够获得正确的输出!删除键10之后,我们只剩下了另外两对。
使用范围过滤器删除后,我们就可以删除地图上的所有内容!