remove

remove は指定した範囲から、特定の値を消去します。

戻り値は削除操作を行った最後を指すイテレータです。これが何のことか、下の動作例をみてください。

次の例では 001122...999 という風に要素が設定された int の vector を作成し、その中から remove を使って 6 の要素を削除します。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
  vector<int> v;
  vector<int>::iterator i;

  // vector の準備
  // これで v が 0,0,1,1,2,2,...,9,9 となります。
  for (int n = 0; n < 10; n++) {
    v.push_back(n);
    v.push_back(n);
  }

  // 内容を出力
  i = v.begin();
  while (i != v.end()) {
    cout << *i;
    i++;
  }
  cout << endl;

  // 6 を削除
  vector<int>::iterator e = remove(v.begin(), v.end(), 6);

  // 内容を出力
  i = v.begin();
  while (i != e) {
    cout << *i;
    i++;
  }
  cout << endl;

  return 0;
}

これを実行すると次のようになりました。

./a.out
00112233445566778899
001122334455778899

確かに 6 がなくなってます。

ここではループは v の先頭 v.begin() から、remove が返した e まで行っています。

注意すべき点は、remove を実行しても、要素そのものは元のままであるという点です。値が詰められるだけです。 このため、e までではなく、v.end() までの内容をダンプするように下記コードを追加すると・・・

  cout << endl;

  // v.end() まで出力
  i = v.begin();
  while (i != v.end()) {
    cout << *i;
    i++;
  }
  cout << endl;

  return 0;
}

実行結果は次のようになります。

./a.out
00112233445566778899
001122334455778899
00112233445577889999

6 という値は削除されましたが、値を削除して値を前に詰めていった結果、後ろの要素は元のまま残っています。 この部分を消去するには erase で消去範囲を指定します。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
  vector<int> v;
  vector<int>::iterator i;

  // vector の準備
  // これで v が 0,0,1,1,2,2,...,9,9 となります。
  for (int n = 0; n < 10; n++) {
    v.push_back(n);
    v.push_back(n);
  }

  // 内容を出力
  i = v.begin();
  while (i != v.end()) {
    cout << *i;
    i++;
  }
  cout << endl;

  // 6 を削除
  vector<int>::iterator e = remove(v.begin(), v.end(), 6);

  // 内容を出力
  i = v.begin();
  while (i != e) {
    cout << *i;
    i++;
  }
  cout << endl;

  // 不要な要素を消去
  v.erase(e, v.end());

  // v.end() まで出力
  i = v.begin();
  while (i != v.end()) {
    cout << *i;
    i++;
  }
  cout << endl;

  return 0;
}

この結果は次のようになります。

./a.out
00112233445566778899
001122334455778899
001122334455778899

このように単に remove を呼んだだけではコンテナのサイズが変わらない点には、注意しましょう。