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 件のコメント:
コメントを投稿