【问题标题】:implementing an unordered map within an unordered map在无序映射中实现无序映射
【发布时间】:2014-09-07 20:42:59
【问题描述】:

我正在从文件中读取数据并尝试将其设置为另一个无序映射中的无序映射,以便我可以有 2 个键用于某个值。该文件包含顶点和从一个到另一个的距离。我正在使用此代码从文件中读取并创建有序地图,但它不起作用。我寻找了有关如何实现无序地图的示例,但我没有在网上找到任何东西。

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <set>


int main()
{
    std::unordered_map<std::string,std::unordered_map<std::string,int>> left_vertex;
    std::set<std::string> vertices;
    int i=0,j=0,distance = 0;
    std::string start_vertex = "",outer_key = " ",inner_key = " ";
    std::unordered_map<std::string,std::unordered_map<std::string,int>>::iterator it;
    std::set<std::string>::iterator it2;

    for(std::string line;std::getline(std::cin,line);)
    {
        std::stringstream line_stream(line);

        for(std::string token;std::getline(line_stream,token,' ');)
        {
            if(i==0)
            {
                start_vertex = token;
                break;
            }

            if(j==0)
            {
                outer_key = token;
                vertices.insert(outer_key);
            }

            if(j==1)
            {
                inner_key = token;
            }
            if(j==2)
            {
                distance = std::stoi(token);
            }
            j++;

        }

        for(it2 = vertices.begin();it2!=vertices.end();it2++)
        {
            if(*it2 == outer_key)
            {
                //left_vertex.insert(std::make_pair(outer_key,std::make_pair(inner_key,distance)));
                left_vertex[outer_key][inner_key]=distance;
            }
            else
            {
                left_vertex[outer_key] = std::make_pair(inner_key,distance);
            }
        }
        outer_key = " ";
        inner_key = " ";
        distance = 0;
        j=0;
        i++;

    }

    for(it = left_vertex.begin(); it != left_vertex.end();it++)
    {
        std::cout<<it->first<<std::endl;
    }

    return 0;
}

我正在读取的文件如下所示。

A 
A B 1
A C 5
B C 2
B D 4
C D 1
C E 4
D E 2

第一行是起始顶点。之后每行的3个元素代表每行第一个元素到第二个元素的距离。

【问题讨论】:

  • 文件是否总是排序的?
  • 是的,文件将始终被排序
  • "..但它不起作用。" - 所以...调试它?这段代码做了什么
  • 顶点名称是否可以简单地映射到一系列连续整数?这些比字符串更容易处理。如果没有,请考虑在进一步处理之前创建这样的映射。
  • @user3325937:它应该是……:这是目标本身,还是只是做你真正想做的工作之前的第一步?因为这样看起来非常低效,所以换个思路:将顶点名称映射到顶点 ID(从 0 开始,如果可能是算法,尽管可能需要映射),将关系信息存储在一个向量中,然后一秒钟内的必要索引(对于每个顶点,紧接在最后一个距离/顶点对之后的位置)。

标签: c++ unordered-map


【解决方案1】:

我在你的代码中遇到了两个问题:

  • std::make_pair 的行没有编译。
  • 对于这种复杂的双地图,您的打印策略是错误的。

除此之外,您的代码几乎完成了您希望它做的事情。
我冒昧地重新格式化了它,让它变得更短更简单——你有几个不必要的for循环。

#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>

int main()
{
    std::unordered_map<std::string, std::unordered_map<std::string, int>> doubleMap;
    std::unordered_map<std::string, std::unordered_map<std::string, int>>::iterator it;
    std::unordered_map<std::string, int>::iterator it2;
    std::string key1, key2, distanceStr;

    std::string line;
    std::getline(std::cin, line); // Read the unwanted line
    while (std::getline(std::cin, line)) {
        std::stringstream line_stream(line);
        std::getline(line_stream, key1, ' ');
        std::getline(line_stream, key2, ' ');
        std::getline(line_stream, distanceStr, ' ');

        doubleMap[key1][key2] = std::stoi(distanceStr);
    }

    for (it = doubleMap.begin(); it != doubleMap.end(); ++it) {
        std::cout << it->first << std::endl;
        for (it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
            std::cout << "  " << it2->first << " " << it2->second << std::endl;
        }
    }

    return 0;
}

当我输入你的文件时,这段代码的输出是这样的:

A
  C 5
  B 1
D
  E 2
C
  D 1
  E 4
B
  D 4
  C 2

【讨论】:

    【解决方案2】:

    您的带有双 unordered_map 的数据结构很有趣。但是,您使用的代码看起来有点过于复杂。

    只需将您的 for(it2 ...) 循环块替换为以下内容:

        if (i!=0)   // for the first line the data is irrelevant
            left_vertex[outer_key][inner_key] = distance;  // just insert !  
    

    在最后添加如下输出代码:

    for (it = left_vertex.begin(); it != left_vertex.end(); it++) {
        std::cout << it->first << std::endl<<"\t";
        for (auto x : it->second)
            std::cout << x.first << x.second<<" ";
        cout << endl; 
    }
    

    允许sse结果:

    A
            B1 C5
    B
            C2 D4
    C
            D1 E4
    D
            E2
    

    其他一些建议:

    对于line_stream 的阅读,您也可以编写类似line_stream&gt;&gt;outer_key&gt;&gt;inner_key&gt;&gt;distance; 的内容,这会使计数器j 和中间令牌无用。

    您还可以在最后检查顶点是否与 inner_keys 一致,因为目前无法确保这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2020-11-01
      • 1970-01-01
      • 2013-08-02
      • 2013-12-11
      • 1970-01-01
      相关资源
      最近更新 更多