访问mulimap中的元素

时间:2016-04-18 23:25:17

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

我正在尝试创建一个程序,该程序从.txt或类似文件中获取数据,并要求用户搜索要搜索的单词。输出应该在上下文中显示关键字,其中包含最初位于其前面的2个单词以及它后面的单词。 (EX:关键字:男孩会输出"男孩跑掉")我能够使用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循环中的代码是错误的,但它是出于测试目的。

2 个答案:

答案 0 :(得分:0)

您需要双向查找:您需要将单词映射到其索引(这是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()是一个需要一对迭代器的东西,它会为你提供一些可以在基于范围的表达式中使用的东西。这不考虑words的范围(如果您选择前两个或前两个单词中的一个作为关键字),但这应该会让您走上正确的轨道。

此外,如果您总是要迭代所有值并且不需要迭代器稳定性,请考虑使用std::map<std::string, std::vector<size_t>>而不是std::multimap<std::string, size_t>。有关详细信息,请参阅this question

答案 1 :(得分:0)

鉴于您的问题陈述,map不合适,因为您立即丢失了所有位置信息,而您还是试图找到解决方法。如果您愿意将所有数据保存在容器中,您也可以将其保存在vector中并执行线性搜索。是的,我知道,理论上 会慢一点,但它很难在实践中获胜......

对于咯咯笑,这里采用<regex>设施完全不同的方法:

// 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));