C++ Map:在地图内部操作地图
C++ Map : manipulate map inside map
我更习惯使用单个地图而不是嵌套地图。所以我很难理解如何处理这个问题。
备注:请不要要求我使用multimap或者boost,我限制使用这个结构
在C++ STL映射中,我有这样的定义
map<string, map<string, string>> exploration; // country --> state --> city
第一个地图代表一对键(国家)和值作为树结构map<string, string>
,代表各自的州和城市。
我知道如何手动填充此结构(硬编码),如下所示:
exploration["Canada"]["Ontario"] = "Toronto";
问题:
稍后将由用户输入上面显示的数据:
> Canada Ontario Toronto
> Canada Alberta Edmonton
> USA Washington Seatle
> USA Nevada Las-Vegas
因此,如果我将此逻辑应用于上面的示例,这是错误的,因为地图不接受重复键
插图(错误):
exploration["Canada"]["Ontario"] = "Toronto";
exploration["Canada"]["Alberta"] = "Edmonton";
插图(我要找的) :
exploration["Canada"]["Ontario"] = "Toronto";
["Alberta"] = "Edmonton";
Canada
**
* *
* *
Ontario Alberta
* *
* *
Toronto Edmonton
我假设的解决方案,
> Canada Ontario Toronto
1个案例:如果探索结构中没有国家(加拿大),我加上省市。
2 case:如果国家(加拿大)存在,那么我在之前输入的数据中加上Ontario和Toronto的长边。
欢迎任何指示、想法或提示。
你的例子很正确。查看下面的代码(在 C++11 中,但同样的推理适用于以前的版本),您可以看到每个国家只在 exploration
地图中插入一次。
代码:
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, map <string, string> > exploration;
exploration["Canada"]["Ontario"] = "Toronto";
exploration["Canada"]["Alberta"] = "Edmonton";
exploration["USA"]["Washington"] = "Seattle";
exploration["USA"]["Nevada"] = "Las Vegas";
cout << "Number of keys: " << exploration.size() << endl;
for (auto country : exploration) {
for (auto city : country.second)
cout << country.first << ":" << city.first << " -> " << city.second << endl;
}
return 0;
}
输出:
Number of keys: 2
Canada:Alberta -> Edmonton
Canada:Ontario -> Toronto
USA:Nevada -> Las Vegas
USA:Washington -> Seattle
让我们一步一步来了解发生了什么:
map<string, map <string, string> > exploration
:定义一个map,其key为字符串,value为其他map。到目前为止是空的。
exploration["Canada"]["Ontario"] = "Toronto"
:首先检查 Canada
在 exploration map
中不存在。因此创建了一个映射,将 Canada
链接到一个空映射。现在,在 exploration["Canada"]
映射中创建了从 Ontario
到 Toronto
的映射。
exploration["Canada"]["Alberta"] = "Edmonton"
:由于Canada
键已经存在于exploration
中,无需重新创建。它只会在已经创建的地图中将 Alberta
映射到 Edmonton
。
同样的推理也适用于 USA
地图。这样,即使是嵌套映射也不会有重复键。 C++ 很棒。
你可以在同一个州拥有两个城市,所以你真的需要map<string, map<string, set<string>>>
但是您之前的操作已经可以使用了。例如:
#include <iostream>
#include <map>
#include <set>
#include <string>
int main() {
std::map<std::string, std::map<std::string, std::set<std::string>>> countries;
countries["Canada"]["Ontario"].insert("Toronto");
countries["Canada"]["Ontario"].insert("Something else");
countries["Canada"]["Alberta"].insert("Edmonton");
for (const auto& country : countries) {
std::cout << "Country: " << country.first << "\n";
for (const auto& statePair : country.second) {
std::cout << "State: " << statePair.first << "\n";
for (const auto& city : statePair.second) {
std::cout << "City: " << city << "\n";
}
}
}
return 0;
}
会输出
Country: Canada
State: Alberta
City: Edmonton
State: Ontario
City: Something else
City: Toronto
编辑:
关于您的后续问题,这应该可以帮助您:
using CountryMap = std::map<std::string, std::map<std::string, std::set<std::string>>>;
bool countryContainsCity(const CountryMap& countryMap, const std::string& country, const std::string& city)
{
for (const auto& country : countryMap[country]) {
for (const auto& statePair : country.second) {
if (statePair.second.find(city)
{
return true;
}
}
}
return false;
}
我更习惯使用单个地图而不是嵌套地图。所以我很难理解如何处理这个问题。
备注:请不要要求我使用multimap或者boost,我限制使用这个结构
在C++ STL映射中,我有这样的定义
map<string, map<string, string>> exploration; // country --> state --> city
第一个地图代表一对键(国家)和值作为树结构map<string, string>
,代表各自的州和城市。
我知道如何手动填充此结构(硬编码),如下所示:
exploration["Canada"]["Ontario"] = "Toronto";
问题:
稍后将由用户输入上面显示的数据:
> Canada Ontario Toronto
> Canada Alberta Edmonton
> USA Washington Seatle
> USA Nevada Las-Vegas
因此,如果我将此逻辑应用于上面的示例,这是错误的,因为地图不接受重复键
插图(错误):
exploration["Canada"]["Ontario"] = "Toronto";
exploration["Canada"]["Alberta"] = "Edmonton";
插图(我要找的) :
exploration["Canada"]["Ontario"] = "Toronto";
["Alberta"] = "Edmonton";
Canada
**
* *
* *
Ontario Alberta
* *
* *
Toronto Edmonton
我假设的解决方案,
> Canada Ontario Toronto
1个案例:如果探索结构中没有国家(加拿大),我加上省市。
2 case:如果国家(加拿大)存在,那么我在之前输入的数据中加上Ontario和Toronto的长边。
欢迎任何指示、想法或提示。
你的例子很正确。查看下面的代码(在 C++11 中,但同样的推理适用于以前的版本),您可以看到每个国家只在 exploration
地图中插入一次。
代码:
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, map <string, string> > exploration;
exploration["Canada"]["Ontario"] = "Toronto";
exploration["Canada"]["Alberta"] = "Edmonton";
exploration["USA"]["Washington"] = "Seattle";
exploration["USA"]["Nevada"] = "Las Vegas";
cout << "Number of keys: " << exploration.size() << endl;
for (auto country : exploration) {
for (auto city : country.second)
cout << country.first << ":" << city.first << " -> " << city.second << endl;
}
return 0;
}
输出:
Number of keys: 2
Canada:Alberta -> Edmonton
Canada:Ontario -> Toronto
USA:Nevada -> Las Vegas
USA:Washington -> Seattle
让我们一步一步来了解发生了什么:
map<string, map <string, string> > exploration
:定义一个map,其key为字符串,value为其他map。到目前为止是空的。exploration["Canada"]["Ontario"] = "Toronto"
:首先检查Canada
在exploration map
中不存在。因此创建了一个映射,将Canada
链接到一个空映射。现在,在exploration["Canada"]
映射中创建了从Ontario
到Toronto
的映射。exploration["Canada"]["Alberta"] = "Edmonton"
:由于Canada
键已经存在于exploration
中,无需重新创建。它只会在已经创建的地图中将Alberta
映射到Edmonton
。
同样的推理也适用于 USA
地图。这样,即使是嵌套映射也不会有重复键。 C++ 很棒。
你可以在同一个州拥有两个城市,所以你真的需要map<string, map<string, set<string>>>
但是您之前的操作已经可以使用了。例如:
#include <iostream>
#include <map>
#include <set>
#include <string>
int main() {
std::map<std::string, std::map<std::string, std::set<std::string>>> countries;
countries["Canada"]["Ontario"].insert("Toronto");
countries["Canada"]["Ontario"].insert("Something else");
countries["Canada"]["Alberta"].insert("Edmonton");
for (const auto& country : countries) {
std::cout << "Country: " << country.first << "\n";
for (const auto& statePair : country.second) {
std::cout << "State: " << statePair.first << "\n";
for (const auto& city : statePair.second) {
std::cout << "City: " << city << "\n";
}
}
}
return 0;
}
会输出
Country: Canada
State: Alberta
City: Edmonton
State: Ontario
City: Something else
City: Toronto
编辑:
关于您的后续问题,这应该可以帮助您:
using CountryMap = std::map<std::string, std::map<std::string, std::set<std::string>>>;
bool countryContainsCity(const CountryMap& countryMap, const std::string& country, const std::string& city)
{
for (const auto& country : countryMap[country]) {
for (const auto& statePair : country.second) {
if (statePair.second.find(city)
{
return true;
}
}
}
return false;
}