访问mulimap中的元素

Accessing elements in a mulimap

本文关键字:元素 mulimap 访问      更新时间:2023-10-16

我正在尝试创建一个程序,该程序从.txt或类似文件中获取数据,并要求用户搜索一个单词。输出应该显示上下文中的关键字,以及它前面和后面的两个单词。(例如:keyword:boy将输出"and The boy run away")我可以使用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循环中的代码是错误的,但这是出于测试目的。

您需要双向查找:您需要将一个单词映射到它的索引(这就是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>。有关详细信息,请参阅此问题。

考虑到您的问题陈述,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));