2011-11-13 24 views
2

ベクトル上の重複要素を消去する方法を知っています。STLベクトルの偶数インデックスの重複要素を消去する

インデックス0、2、4、6、8、...の重複要素を削除するにはどうすればよいですか?

例:

 
index : 0 1 2 3 4 5 6 7 8 9 
data : a b a d b f a h b k 
     ^^^^^
     ^^^^
       ^--same-^ 
     ^^ ^
     ^^ ^
     ^-----same--^ 
after erasing 
data : a b d b f h k 

after concatenatiom 
data : a b d b f h 
+0

すべての複製物を消去しますか? (あなたの例が示唆しているように)、またはちょうど**隣接**のもの( 'std :: unique'は何ですか?) –

+0

あなたの例が間違っているか、 'erase'と' std :: unique'を使ったアプローチではこの問題は解決しません。これを明確にしてください。 – moooeeeep

+0

ところで、あなたの例では "k"が最終結果にないのはなぜですか? –

答えて

2

何のライブラリ関数は、このためにありません。何を求めているのかは、例の場合と同じようにstd::uniqueを使用した場合と似ていません。に隣接するの重複が削除されるためです。あなたはここで自分で仕事の大部分をしなければなりません。

セットを作成します。奇数のインデックスをスキップして、ベクトルをループします。ループするときに、その要素がセット内にあるかどうかを確認します。そうである場合は、そのインデックスにマークを付けて削除します。それ以外の場合は、要素をセットに追加します。マークされたすべてのインデックスをベクターから削除します。 std::removeまたはstd::remove_ifは、インデックスではなく要素値で機能するため、使用できません。普通のfor forループを使わなければなりません。

特定の値を違法と指定すると、インデックスを追跡するのではなく、実際に要素をその不正な値に変更することができます。その後、を使用します。std::removeです。

0

this非常に良い投稿Fred Nurkで与えられた提案の1つ(非常に類似した質問)を取ることができます。 偶数(または奇数)のインデックス付き要素のみをタッチするには、さらに++x;が必要です。

例:

set<string> found; 
for (list<string>::iterator x = the_list.begin(); x != the_list.end();) { 
    if (!found.insert(*x).second) { 
    x = the_list.erase(x); 
    } 
    else { 
    ++x; 
    } 
    ++x; // <-- one increment added to skip the odd-indexed elements 
} 
2

これは特にエレガントなコードではないが、それはデフォルトのハッシュ限り動作するはずとの比較が十分であり、合理的に効率的であるべきである。

template <typename T> 
void RemoveEvenDuplicates(std::vector<T>& v) { 

    std::unordered_set<T> s; 
    std::vector<T>::size_type i = 0; 

    auto last = std::remove_if(
     v.begin(), 
     v.end(), 
     [&s, &i] (const T& element) -> bool { 
      if (i++ % 2 == 0) { 
       auto pair = s.insert(element); 
       return !pair.second; 
      } 
      return false; 
     } 
    ); 

    v.erase(last, v.end()); 

} 

void main() { 

    std::vector<std::string> v; 
    v.push_back("a"); 
    v.push_back("b"); 
    v.push_back("a"); 
    v.push_back("d"); 
    v.push_back("b"); 
    v.push_back("f"); 
    v.push_back("a"); 
    v.push_back("h"); 
    v.push_back("b"); 
    v.push_back("k"); 

    RemoveEvenDuplicates(v); 

} 

RemoveEvenDuplicatesを呼び出すと、ベクトルは次のようになります。

[7]("a","b","d","b","f","h","k") 
関連する問題