2016-04-18 63 views
2

我試圖創建一個程序,它接收來自.txt或類似文件的數據並要求用戶輸入要搜索的單詞。輸出結果應該顯示關鍵字與原來在它前面的兩個單詞以及它後面的單詞。 (EX:關鍵字:男孩會輸出「,男孩跑了」)我可以找到該文件中的所有關鍵字與equal_range()函數的實例,但我不知道如何遍歷地圖中的數據訪問其他文字的上下文。這裏是我的代碼到目前爲止:訪問mulimap中的元素

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循環底部的代碼是錯誤的,但它是用於測試目的。

回答

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

+0

是as_range是否需要從算法,數學,向量和iostream以外的其他東西中加入?我的編譯器告訴我這是未定義的,我無法在任何地方找到明確的答案 – littlenv

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