お世話になります。先回は大変お世話になりました本日はtemplate の特殊化について
の質問です。
以下は文字列の出現回数から出現率を求めvector コンテナに格納するプログラムです。
この時、struct count_ch 及びstruct insert_frequency のstd::map<T1, T2> について
他の型も適用したいので、
このようにtemplate 化してみるものの要領を得ません。よろしくお願いします。
template<typename T1, typename T2>
struct Insert_frequency {
void operator()(std::map<const T1 t1, const T2& t2>::value_type pair)
const
{
vnode.push_back(pair.second / static_cast<const T2& t2>
(hist.size()));
Show<const T2& t2>(pair.second / static_cast<const T2& t2>
(hist.size()));
}
};
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
/**@brief 出現頻度を昇順に並べたコンテナ */
std::vector<double > vnode;
/**@brief <出現文字, 出現回数>が収まったコンテナ */
std::map<char, double > hist;
/**@brief データ */
std::string data = ABBCDAEFADB;
/** @brief コンソール出力 */
template<typename T>
void Show(const T& t_) { std::cout << t_ << std::endl; }
/** @brief データをからhist を作成 */
struct count_ch
{
std::map<char, double >& _hist;
count_ch(std::map<char, double >& hist) : _hist(hist) {}
void operator()(char ch) { ++_hist[ch]; }
};
/** @brief 出現頻度を求める */
struct insert_frequency
{
void operator()(std::map<char, double >::value_type pair) const
{
vnode.push_back(pair.second / static_cast<double >
(hist.size()));
Show<double >(pair.second / static_cast<double >(hist.size()));
}
};
int main()
{
std::for_each(data.begin(), data.end(), count_ch(hist) );
std::for_each(hist.begin(), hist.end(), insert_frequency() );
return 0;
}
insert_frequencyをこんな感じにしたいということですか。
template<typename T1, typename T2>
struct insert_frequency
{
void operator()(typename std::map<T1, T2>::value_type pair) const
{
vnode.push_back(pair.second / static_cast<T2>(hist.size()));
Show(pair.second / static_cast<T2>(hist.size()));
}
};
std::for_each(hist.begin(), hist.end(), insert_frequency<char, double>() );
そもそももっと汎用的にするべきな気がしますが。
なんとなくこんな風にしてみましたが、やっつけなので微妙かも。
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
template<typename T>
struct count_ch
{
T& hist_;
count_ch(T& hist) : hist_(hist) {}
template<typename C> void operator()(C ch) { ++hist_[ch]; }
};
template<typename T>
struct calc_frequency
{
T size_;
calc_frequency(const T& size) : size_(size) {}
template<typename Y> T operator()(const Y& pair)const
{
return pair.second / size_;
}
};
struct print
{
template<typename T> void operator()(const T& t) const
{
std::cout << t << std::endl;
}
};
int
main(int ac, char* av[])
{
std::string data = ABBCCCDDDD;
std::map<char, double> hist;
std::for_each(data.begin(), data.end(), count_ch<std::map<char, double>
>(hist) );
std::vector<double> vnode;
// 元処理だと分母がhist.size()になってますが、それだと [各文字の登場
数 / 登場した種類数] だと思うので
// 例えばdata=DDDDの場合、Dの出現率は4になって1を超えるかと。
// std::transform(hist.begin(), hist.end(), std::back_inserter(vnode),
calc_frequency<double>(hist.size()) );
std::transform(hist.begin(), hist.end(), std::back_inserter(vnode),
calc_frequency<double>(data.size()) );
std::sort(vnode.begin(), vnode.end()); // 元処理にはなさそうでしたがコ
メントから
std::for_each(vnode.begin(), vnode.end(), print() );
return 0;
}
蛇足ですが、
> 要領を得ません。
だけでは何が問題だと認識しているのか他人には伝わらないと思います。
# それも見えていないから要領を得ないのでしょうが…。
また、templateの特殊化(specialization)が主題の内容でもない気が。
Ban さんありがとうございました、質問のしかたが的を得ていなくて失礼しました。