2

我更习惯于单个地图而不是嵌套地图。所以我很难理解如何处理这个问题。

备注:请不要要求我使用 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

因此,如果我将此逻辑应用于上面的示例,这是错误的,因为 map 不接受重复的键

插图(错误)

exploration["Canada"]["Ontario"] = "Toronto";
exploration["Canada"]["Alberta"] = "Edmonton";

插图(我在找什么)

exploration["Canada"]["Ontario"] = "Toronto";
                     ["Alberta"] = "Edmonton";

        Canada
          **
         *  *     
        *    *
     Ontario Alberta
       *        *
      *          *
   Toronto     Edmonton  

我假设的解决方案,

> Canada Ontario Toronto

1 案例:如果勘探结构中不存在国家(加拿大),我添加它以及省及其城市。

2 案例:如果国家(加拿大)存在,那么我在之前输入的数据中添加安大略和多伦多的长边。

欢迎任何指示、想法或提示。

4

2 回答 2

4

你的例子很对。查看下面的代码(在 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

让我们一步一步来了解发生了什么:

  1. map<string, map <string, string> > exploration: 定义一个键是字符串,值是其他映射的映射。到目前为止它是空的。
  2. exploration["Canada"]["Ontario"] = "Toronto"Canada: 首先它检查exploration map. 因此,创建一个映射链接Canada到一个空映射。现在,在地图内部创建了一个从Ontario到的映射。Torontoexploration["Canada"]
  3. exploration["Canada"]["Alberta"] = "Edmonton": 由于Canada密钥已经存在于 中exploration,无需重新创建。它只会映射AlbertaEdmonton已创建的地图中。

同样的道理也适用于USA地图。这样,即使使用嵌套映射也不会有重复的键。C++ 很棒。

于 2018-03-22T04:47:19.273 回答
1

你可以在同一个州有两个城市,所以你真的需要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;
}
于 2018-03-22T04:57:42.107 回答