6.03.2012

C++: Handy version of sequence algorithms

シーケンス(vector/string)操作アルゴリズムの便利バージョン

・概要

UNIQUE: ソート処理を行なってからユニーク・アルゴリズムを実行し、不要な部分を削除する。
http://mogproject.blogspot.jp/2011/08/c-remove-duplicates-from-vector.html

REMOVE, REMOVE_IF: 削除アルゴリズムを実行した後、不要な部分を削除する。

ROTATE: 指定されたカウント分、シーケンスを左方向にローテーションする。
      負数が指定された場合は、逆に右方向へローテーションする。

・コード

template <typename T> void UNIQUE(T &v) {
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());
}
template <typename T, typename U> void REMOVE(T &v, U const& val) {
  v.erase(std::remove(v.begin(), v.end(), val), v.end());
}
template <typename T, typename U> void REMOVE_IF(T &v, U predicate) {
  v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());
}
template <typename T> void ROTATE(T &v, int count) {
  count %= static_cast<int>(v.size());
  if (count < 0) { std::rotate(v.rbegin(), v.rbegin() - count, v.rend()); }
  else { std::rotate(v.begin(), v.begin() + count, v.end()); }
}

・実行例

#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>

template <typename T> void UNIQUE(T &v) {
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(), v.end()), v.end());
}
template <typename T, typename U> void REMOVE(T &v, U const& val) {
  v.erase(std::remove(v.begin(), v.end(), val), v.end());
}
template <typename T, typename U> void REMOVE_IF(T &v, U predicate) {
  v.erase(std::remove_if(v.begin(), v.end(), predicate), v.end());
}
template <typename T> void ROTATE(T &v, int count) {
  count %= static_cast<int>(v.size());
  if (count < 0) { std::rotate(v.rbegin(), v.rbegin() - count, v.rend()); }
  else { std::rotate(v.begin(), v.begin() + count, v.end()); }
}

std::vector<int> create_vector(int t1, int t2, int t3, int t4, int t5) {
  std::vector<int> v;
  v.push_back(t1); v.push_back(t2); v.push_back(t3); v.push_back(t4); v.push_back(t5);
  return v;
}

using namespace std;

string output(vector<int> const& v, string const& s) {
  stringstream ss;
  for (int i = 0; i < (int)v.size(); ++i) ss << v[i] << ", ";
  ss << s << endl;
  return ss.str();
}
bool is_odd(int x) { return x % 2; }

int main() {
  vector<int> v_init = create_vector(1, 2, 1, 3, 2), v;
  string s_init = "ABACB", s;

  v = v_init; s = s_init;
  cout << "before UNIQUE:     " << output(v, s);
  cout << "after  UNIQUE:     " << output((UNIQUE(v), v), (UNIQUE(s), s));

  v = v_init; s = s_init;
  cout << "before REMOVE:     " << output(v, s);
  cout << "after  REMOVE:     " << output((REMOVE(v, 2), v), (REMOVE(s, 'B'), s));

  v = v_init; s = s_init;
  cout << "before REMOVE_IF:  " << output(v, s);
  cout << "after  REMOVE_IF:  " << output((REMOVE_IF(v, is_odd), v), (REMOVE_IF(s, is_odd), s));

  v = create_vector(1, 2, 3, 4, 5); s = "ABCDE";
  cout << "before ROTATE:     " << output(v, s);
  cout << "after  ROTATE(2):  " << output((ROTATE(v, 2), v), (ROTATE(s, 2), s));
  cout << "after  ROTATE(-2): " << output((ROTATE(v, -2), v), (ROTATE(s, -2), s));
  cout << "after  ROTATE(12): " << output((ROTATE(v, 12), v), (ROTATE(s, 12), s));

  return 0;
}

・出力例

before UNIQUE:     1, 2, 1, 3, 2, ABACB
after  UNIQUE:     1, 2, 3, ABC
before REMOVE:     1, 2, 1, 3, 2, ABACB
after  REMOVE:     1, 1, 3, AAC
before REMOVE_IF:  1, 2, 1, 3, 2, ABACB
after  REMOVE_IF:  2, 2, BB
before ROTATE:     1, 2, 3, 4, 5, ABCDE
after  ROTATE(2):  3, 4, 5, 1, 2, CDEAB
after  ROTATE(-2): 1, 2, 3, 4, 5, ABCDE
after  ROTATE(12): 3, 4, 5, 1, 2, CDEAB

0 件のコメント:

コメントを投稿