3.10.2013

Histogram in C++

C++: ヒストグラムの作成

first と last という 2つのイテレータからその範囲内の連続する値をカウントし
その個数と値の pair を vector にして返すテンプレート関数 encodeList を作成。
ソート済みのリストに対してこれを適用すれば、ヒストグラムを作成することができる。

コード

using namespace std;

template <typename Iterator>
vector<pair<int , typename Iterator::value_type> > encodeList(Iterator first, Iterator last) {
  vector<pair<int , typename Iterator::value_type> > ret;
  for (Iterator i = first; i != last;) {
    Iterator j = i;
    while (j != last && *i == *j) ++j;
    ret.push_back(make_pair(j - i, *i));
    i = j;
  }
  return ret;
}

実行例

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

using namespace std;

template <typename Iterator>
vector<pair<int , typename Iterator::value_type> > encodeList(Iterator first, Iterator last) {
  vector<pair<int , typename Iterator::value_type> > ret;
  for (Iterator i = first; i != last;) {
    Iterator j = i;
    while (j != last && *i == *j) ++j;
    ret.push_back(make_pair(j - i, *i));
    i = j;
  }
  return ret;
}

template <typename T>
std::ostream & operator<<(std::ostream & stream, std::vector<T> & v) {
  stream << "[";
  for(typeof(v.begin()) i = v.begin(); i != v.end(); ++i) {
    if (i != v.begin()) { stream << ", "; }
    stream << *i;
  }
  stream << "]";
  return stream;
}
template <typename T, typename U>
std::ostream & operator<<(std::ostream & stream, std::pair<T, U> & p) {
  stream << "(" << p.first << ", " << p.second << ")";
  return stream;
}
#define all(a) (a).begin(),(a).end()
template <typename T>
void printResult(T v) {
  cout << v << endl;
  vector<pair<int , typename T::iterator::value_type> > result = encodeList(all(v));
  cout << result << endl;
}

int main() {
  vector<int> v1, v2;
  for (int i = 1; i < 4; ++i) for (int j = 0; j < i * 2; ++j) v1.push_back(i);
  printResult(v1);
  // [1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
  // [(2, 1), (4, 2), (6, 3)]

  printResult(v2);
  // []
  // []

  string s = "aabbbaac";
  printResult(s);
  // aabbbaac
  // [(2, a), (3, b), (2, a), (1, c)]

  sort(all(s));
  printResult(s);
  // aaaabbbc
  // [(4, a), (3, b), (1, c)]

  return 0;
}

0 件のコメント:

コメントを投稿