2016-09-26 5 views
0

したがって、最もよく使われる単語をファイル内で見つける必要があります。ペア内の個々の要素に基づいてペアのベクトルの重複要素を削除する

私はvector<pair<string, int> > wordListを持っています。ファイル内のすべての単語とその頻度を記録しています。この部分はうまく動作します。

問題は、出力に各単語の複数のバージョンが表示されることです。

  • 負荷再び1〜
  • ゴーの周波数を持つベクターにすべての単語と単語が二回現れた場合、そのカウント
  • 一部を増やす:これは私が計算の方法は、それがあったためであります私は、同じ単語の複数のエントリを削除することですヘルプが必要です。

    for(int j = 0; j < wordList.size(); j++) 
    { 
    

これは私の現在のアプローチです。この関数はすべての単語を集計します。問題は、forループ 内にある行wordList.eraseが範囲外のエラーを生成するため、重複したエントリをそのように削除できないということです。 私もunique()アプローチを試みましたが、動作していないようですが、いくつかのエントリを削除するだけです。

ペアのベクトルを一意の要素に限定する最も効率的な方法は何ですか?

+1

あなたは 'std :: map'に精通していますか? – Beta

+0

はい、しかし、私はこのリストが降順で印刷されている必要があります。正しくリコールすれば、その中の特定の値に基づいてマップをソートすることはできません。私が間違っている? –

+0

ループ内のベクトルから要素を消去すると、サイズが変化していると考える必要があります。要素iを消去すると、次の要素はi + 1ではなくiです。 – user463035818

答えて

0

次のようなものを使用可能性があります

std::map<std::string, std::size_t> 
compute_frequency(const std::vector<std::string>& words) 
{ 
    std::map<std::string, std::size_t> res; 

    for (const auto& word : words) { 
     ++res[word]; 
    } 
    return res; 
} 


void test(const std::vector<std::string>& words) 
{ 
    const auto m = compute_frequency(); 
    std::vector<std::pair<std::string, std::size_t>> v(m.begin(), m.end()); 

    auto myless = [](const auto& lhs, const auto& rhs) { 
     //return lhs.first > rhs.first; // by decreasing word 
              // (then you may add the comp in map directly) 
     return lhs.second > rhs.second; // by decreasing frequency 
    }; 
    std::sort(v.begin(), v.end(), myless); 
    for (const auto& p : v) { 
     std::cout << p.first << " appears " << p.second << std::endl; 
    } 

を)。

+0

ありがとう、私はマップを使用し、私はそれを働かせました。もちろん、プログラムの他の部分では4つの問題がありますが、私は単語とその頻度の簡潔なリストを持っています –

0

あなたは可能性のある問題を持つあなたは、ベクトルを反復処理している間、あなたはベクターから削除されているので、これはリストのサイズを変更して、私は++とJ ++エントリを飛び越えることができますし、いくつかの

あなたを逃してしまいます

for(int j = 0; j < wordList.size(); j++) { 
    for(int k = j+1; k < wordList.size(); /*no increment*/) { 
     if(wordList[j].first == wordList[k].first) 
     { 
      wordList[j].second++; 
      wordList.erase(wordList.begin()+k); 
     } else { 
      k++; // increment only if no element was erased ! 
     } 
    } 
} 

あなたがループ内で消去する場合:ベクトルはすでに

0

はこれを試してみてください言葉が含まれているかどうかを判断するために、ベクターに追加する前に検索を()はstd ::セットを使用するか、または実行を検討したいです消去後にそれを考慮する必要があります要素k、次の要素はk、k + 1ではなく、要素が消去されていない場合にのみインクリメントする必要があります。入力を知らなければ、境界外のエラーがなぜ出現したのかは分かりませんが、それが原因です。

また、各ペアを2回確認する必要はありません。 2番目のループはj + 1から始めることができます。

PS:あなたの質問にコメントに記載されているように、代わりにstd::mapを使用することをお勧めします。後でベクターが必要な場合でも(例:hereを参照)。

関連する問題