【问题标题】:Accessing elements in a mulimap访问 mulimap 中的元素
【发布时间】:2016-08-10 21:34:15
【问题描述】:

我正在尝试创建一个程序,该程序从 .txt 或类似文件中获取数据并要求用户输入要搜索的单词。输出应在上下文中显示关键字,其中包含最初位于其前面和后面的 2 个单词。 (例如:关键字:男孩会输出“男孩跑了”)我可以使用 equal_range() 函数在文件中找到关键字的所有实例,但是我不知道如何遍历地图中的数据访问上下文的其他词。到目前为止,这是我的代码:

typedef multimap<string, int> templateMap;
templateMap wordMap;
typedef pair<templateMap::iterator, templateMap::iterator> searchTemplate;
searchTemplate search;
typedef pair<templateMap::const_iterator, templateMap::const_iterator> innerIteratorTemplate;
multimap<string, int>::iterator tempMap;
string tempWord;
string keyword;

// omitted code

for (size_t i = 0; !inData.eof(); i++)  
{
    inData >> tempWord;
    wordMap.insert(pair<string, int>(tempWord, i));
}

search = wordMap.equal_range(keyword);

for (multimap<string, int>::iterator itr = search.first; itr != search.second; ++itr)
{
    cout << "The keyword " << keyword << " is found at location " << itr->second << endl;

    tempMap = itr;
    itr->second = itr->second - 2;
    cout << itr->first << endl;
}

我知道底部for循环中的代码是错误的,但它是出于测试目的。

【问题讨论】:

    标签: c++ c++11 iteration key-value multi-mapping


    【解决方案1】:

    鉴于您的问题陈述,map 不合适,因为您会立即丢失所有位置信息,并且您只能尝试寻找解决方法。如果您愿意将所有数据保存在一个容器中,您不妨将其保存在vector 中并执行线性搜索。是的,我知道,它理论上会慢一些,但很有可能它不会在实践中......

    对于咯咯笑声,这是使用 &lt;regex&gt; 设施的完全不同的方法:

    // Data.
    string const text = "Pack my box with five dozen liquor jugs. The quick brown fox jumps over the lazy dog. The five boxing wizards jump quickly.";
    
    // Word to search for.
    string target;
    cin >> target;
    
    // Capture the target and up to two words before and after.
    regex const context(R"((?:([^\s]+)\s)?(?:([^\s]+)\s)?()" + target + R"()(?:\s([^\s]+))?(?:\s([^\s]+))?)");
    
    // Perform search.
    smatch matches;
    regex_search(text, matches, context);
    
    // Print results.
    copy_if(matches.begin() + 1, matches.end(), ostream_iterator<string>(cout, "\n"), mem_fn(&smatch::value_type::matched));
    

    【讨论】:

      【解决方案2】:

      您需要双向查找:您需要将一个词映射到它的索引(这就是 wordMap 的用途),另外您需要将一个索引映射到它的词(这就是您所缺少的)。因此,让我们添加它,并修复您的初始循环:

      std::vector<std::string> words;
      while (inData >> tempWord) {
          wordMap.insert(std::make_pair(tempWord, words.size()));
          words.push_back(tempWord);
      }
      

      现在,我们拥有它是双向的 - 因为words 允许按索引查找。因此,我们有:

      for (auto const& pair : as_range(wordMap.equal_range(keyword))) {
          for (size_t idx = pair.second - 2; idx < pair.second + 3; ++idx) {
              std::cout << words[idx] << ' ';
          }
          std::cout << '\n';
      }
      

      as_range() 是一个接受一对迭代器的东西,并给你一些你可以在基于范围的 for 表达式中使用的东西。这不考虑words 的范围(如果您选择前两个或最后两个词中的一个作为关键字),但这应该会让您走上正轨。


      此外,如果您总是要迭代所有值并且不需要迭代器稳定性,请考虑使用std::map&lt;std::string, std::vector&lt;size_t&gt;&gt; 而不是std::multimap&lt;std::string, size_t&gt;。请参阅this question 了解更多信息。

      【讨论】:

      • 除了算法、数学、向量和 iostream 之外,as_range 是否需要包含在内?我的编译器告诉我它是未定义的,我在任何地方都找不到明确的答案
      猜你喜欢
      • 1970-01-01
      • 2017-05-16
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多