除外された要素はいずこへ unique, remove_if,,

  • unique で重複していた要素群も知りたい
  • remove_if で、除外された要素群もとりたい

このようなことが意外に簡単にできないということで、自分の思い込みで今日はひどい目にあった。つまり、真実はこういうことだった。

  • unique を使った後に、内容が意味をなすのは、begin()からuniqueの返す反復子までの領域であり、uniqueの返す反復子からend() までの領域の中身はめちゃめちゃになる。同じように、
  • remove_if を使った後に、内容が意味をなすのは、begin()からremove_ifの返す反復子までの領域でありremove_ifの返す反復子からend() までの領域の中身はめちゃめちゃになる。

これに対し、私が致命的に勘違いしていた点といえば、unique, remove_if ともに、除外された要素たちはもれなく、ぞれぞれ、unique/remove_ifが返した反復子からend()の中にきちんと詰められているものと思い込んでいたことだ。
そう、俺はまたてっきり、こいつら(unique, remove_if)は、コンテナの内容を、存続条件を満たしている要素が入る領域とそうでない要素が入る領域、つまり2つの領域に振り分けてくれるアルゴリズムだとばかり思っていたのだが、どうやらそうは問屋がおろしていなかったようだぜ。こいつらは、「存続条件を満たしている要素が入る領域のみを作成提供し、存続条件を満たしていない要素はどこか異次元の彼方へ消し去ってしまうし、存続条件を満たさない要素が居座る領域を用意する気なども一切ないアルゴリズム」だったというわけさ。
あー、そういやEffectiveSTLに書いてあったなー。どこかにこういう話あったわ。unique の話だったか。
こういう場合、つまり、条件を満たす要素と満たさない要素でコンテナを整理したいときはやはりソートして、upper_bound とかlower_boundとか使ってやるしかないのだろうか。いや、remove_copy_ifで条件を満たす要素のみフラグをつけて、今度は逆に条件を満たさない側が残るようにもう一回remove_if するとか?なんかいろいろ考えられそうだが定番はないのだろうか。
あー、またEffectiveSTL読もう。
あー、remove_ifに関してはpartitionというのがあるのかなるほどなこれはこれで使えそうだ、しかし、uniqueの場合はどうだ、重複削除はできても重複してるやつらだけを取り出すのは結局別の手段によるしかなさそうだ。