【问题标题】:c++: use map as value of another mapc ++:使用地图作为另一个地图的值
【发布时间】:2013-11-02 23:31:51
【问题描述】:

我只是想知道我是否可以使用“复杂”的地图作为另一个地图的价值。我已经自定义了几个结构如下:

typedef std::vector<std::string> pattern;
typedef std::map<int, std::vector<pattern>> dimPatternsMap;
typedef std::map<int, dimPatternsMap> supportDimMapMap;

好的,让我解释一下这些事情...pattern 是一个字符串向量。对于“较小”映射dimPatternsMap,键是一个整数,它是模式的维度(包含字符串的向量的大小),值是包含模式的向量(这是向量的向量...)。

“更大”的映射supportDimMapMap 也使用整数作为键值,但使用dimPatternsMap 作为其值。键的意思是“支持计数”。

现在我开始构建这个“复杂”的地图:

supportDimMapMap currReverseMap;
pattern p = getItFromSomePlace();  //I just omit the process I got pattern and its support
int support = getItFromSomePlaceToo();

if(currReverseMap.find(support) == currReverseMap.end()) {
    dimPatternsMap newDpm;

    std::vector<pattern> newPatterns;
    newPatterns.push_back(currPattern);
    newDpm[dim] = newPatterns;

    currReverseMap[support] = newDpm;

} else{
    dimPatternsMap currDpm = currReverseMap[support];

    if(currDpm.find(dim) == currDpm.end()) {
        std::vector<pattern> currDimPatterns;
        currDimPatterns.push_back(currPattern);

        currDpm[dim] = currDimPatterns;
    } else {
        currDpm[dim].push_back(currPattern);
    }
}

请原谅我的代码真的是一团糟……

但是当我想遍历地图时:

for(supportDimMapMap::iterator iter = currReverseMap.begin(); iter != currReverseMap.end(); ++iter) {
        int support = iter->first;
        dimPatternsMap dpm = iter->second;

        for(dimPatternsMap::iterator ittt = dpm.begin(); ittt != dpm.end(); ++ittt) {
            int dim = ittt->first;
            std::vector<pattern> patterns = ittt->second;
            int s = patterns.size();
        }
}

我发现s 的值始终为 1,这意味着对于每个唯一的支持值以及该支持值的每个维度,只有一个模式!但是当我在地图构建过程中调试我的代码时,我确实发现大小不是1 - 我实际上成功地将新模式添加到地图中......但是当涉及到遍历时,所有大小都变为1而我没有不知道为什么……

任何建议或解释将不胜感激!谢谢!!

【问题讨论】:

  • 您实际上根本不需要find 调用,因为operator[] 将在键为新时默认构造一个值,而默认构造的容器是一个空容器。整个代码块可以重写currReverseMap[support][dim].push_back(pattern);
  • 我想我应该说默认构造的容器通常是空的。 std::array&lt;T,N&gt; 是一个值得注意的反例。
  • 我仍然不确定我是否真的正确理解了该代码,但我相当确定您的输出没有任何问题:据我所知,您总是将大小为 1 的向量添加到您的地图,因此您的 s 应该始终为 1 - 您的地图总大小有更多元素(尽管您似乎甚至没有在 else 块中添加任何内容)但在最底部它应该始终是大小 1跨度>

标签: c++ vector map text-mining stdmap


【解决方案1】:
dimPatternsMap currDpm = currReverseMap[support];

currDpmcurrReverseMap[support] 的副本。它不是同一个对象。因此,当您对 currDpm 进行更改时,currReverseMap 中的任何内容都不会发生变化。

另一方面,如果您使用参考:

dimPatternsMap& currDpm = currReverseMap[support];

那么currDpmcurrReverseMap[support] 确实是同一个对象,所以后面使用currDpm 的语句将真正改变currReverseMap 中的值。

在其他一些地方,您的代码也可以从引用中受益。

【讨论】:

    【解决方案2】:

    我的猜测:您应该在 else 中使用引用:

    dimPatternsMap& currDpm = currReverseMap[support];
    

    您当前的代码会创建一个副本,而不是使用原始地图。

    【讨论】:

      【解决方案3】:

      你的问题是这一行:

      dimPatternsMap currDpm = currReverseMap[support];
      

      根据它后面的代码,它想这样读:

      dimPatternsMap& currDpm = currReverseMap[support];
      

      如果没有&amp;,您将修改条目的副本而不是现有条目。

      【讨论】:

        【解决方案4】:

        您的代码正在复制下面的对象,请尝试使用更多引用和迭代器(例如,find() 已经为您提供了一个元素,如果它被发现的话)。

        例如,dimPatternsMap currDpm = currReverseMap[support]; 实际上在您的结构中复制了一个地图,并向其中添加了一个元素(而不是原始元素)。请尝试使用参考。

        【讨论】:

          猜你喜欢
          • 2016-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多