2016-04-18 10 views
2

私は、.txtまたは類似のファイルからデータを取り込み、検索する単語をユーザに尋ねるプログラムを作成しようとしています。出力には、元々はその前にあった2つの単語だけでなくその背後にもキーワードが表示されます。 (EX:keyword:boyは "and boy was run away"と出力しました)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の境界を考慮しません(最初の2つの単語または最後の2つの単語のいずれかをキーワードとして選択する場合)が、正しいトラックに置く必要があります。あなたは、常にすべての値を反復処理することになるだろうとイテレータの安定性を必要としない場合


また、std::map<std::string, std::vector<size_t>>代わりのstd::multimap<std::string, size_t>を使用することを検討してください。詳細はthis questionを参照してください。

+0

ですアルゴリズム、数学、ベクトル、およびiostream以外の何かからインクルードする必要があるas_rangeの何か?私のコンパイラはそれが未定義であると私に伝え、私はどこでも明確な答えを見つけることができません – 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)); 
関連する問題