よろしくです。
文字の出現回数をヒストグラムといいますか、文字種別に出現回数をカウントして
文字コード、出現回数をメンバにもつクラスに取得し。
更にset コンテナを使って操作したいのですが、プログラムを書ききれません
教えてください。
#pragma once
#include <set>
#include <iostream>
using namespace std;
char testData[] =
{aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz};
class imageData {
public:
/*
* Default Constructor
*/
imageData() : m_nCount(0), m_nCode(0)
{
}
/*
* Constructor
*/
imageData( int m_nCount_, int m_nCode_ ) : m_nCount(m_nCount_),
m_nCode(m_nCode_)
{
}
bool operator<(const imageData& obj) const { return m_nCount <
obj.m_nCount; }
/** このオーバーロド関数はなんとなく、こんな雰囲で使うんだろうな的な感じ
で書きました */
bool operator()(const imageData& lhs, const imageData& rhs ) const {
return lhs.m_nCode < rhs.m_nCode; }
/*
* getter
*/
int GetCode(){ return m_nCode; }
int GetCount(){ return m_nCount; }
/*
* setter
*/
void Set(int lhs, int rhs ) {
m_nCount = lhs;
m_nCode = rhs;
}
private:
int m_nCode; // 文字コード
int m_nCount; // 出現回数
};
int main(void)
{
imageData id;
int len = sizeof(testData);
int nCount_ = 0;
int nCode_ = 0;
set<imageData> s;
/** 初期化 */
id.Set(0, 0);
for(int i = 0; i < 256; i++)
{
id.Set(i, 0);
s.insert(id);
}
set<imageData>::iterator it = s.begin();
for(int i = 0; i < len; ++i) {
nCount_ = testData[i];
/** ここで出現回数をインクリしたい。そのためには
nCount_ をset コンテナから探索し、その相方の出現回数を
取得し+1したのち、コンテナに代入すればいいのだが・・・・
*/
s.insert(imageData( nCount_, nCode_));
nCode_ = 0;
it++;
}
return 0;
}
mapつかえばこんだけ。 VC++10で検証。
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string data
= aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz
;
map<char,int> hist;
for_each( data.begin(), data.end(), [&](char ch) { ++hist[ch]; });
for_each( hist.begin(), hist.end(), [](map<char,int>::value_type pair)
{ cout << pair.first << ':' << pair.second << endl;});
}
実行結果:
a:20
b:19
c:33
x:1
y:1
z:1
ありがとうございます
for_each( data.begin(), data.end(), [&](char ch) { ++hist[ch]; });
の [&](char ch) { ++hist[ch]; }
この部分は何をやっているのでしょうか?
文字の出現回数を++してます。
重ね重ねありがとうございます。
なるほどmap pairの2番目を操作してるのですね
あと、どうしてもわからない部分なのですが、 [&](char ch)この部分の
[&] これは一体何でしょうか?\[&\] C++ とか検索するのですが、全く情報が出てきま
せん・・・
お分かりになる方教えてくださいませ。
お世話になりました。ありがとうございました。
お世話になります。もう一点教えて頂けないでしょうか
επιστημη さんに示していただいた、ラムダ式の方法ではなく
「関数オブジェクト」による書き方を教えて頂きたいのですが。
operator() を、このmap コンテナのどの部分に適用していいものか分りません。
よろしくお願いします。
こんなのしか思いつかなかった orz
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string data
=
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz
;
map<char,int> hist;
struct hoge : public std::binary_function<char, map<char, int>*, char>
{
char operator()(char ch, map<char,int>* hist) const {
++(*hist)[ch]; return ch;
}
};
for_each( data.begin(), data.end(), bind2nd(hoge(), &hist));
struct moge {
void operator()(map<char, int>::value_type pair) { cout << pair.first <<
':' << pair.second << endl; }
};
for_each( hist.begin(), hist.end(), moge() );
}
↓のほうがいいかも。
struct hoge
{
map<char, int>& _hist;
hoge(map<char, int>& hist) : _hist(hist) {}
void operator()(char ch) { ++_hist[ch]; }
};
for_each( data.begin(), data.end(), hoge(hist));
void でも動くのか。。。
struct hoge : public std::binary_function<char, map<char, int>*, void>
{
void operator()(char ch, map<char,int>* hist) const {
++(*hist)[ch];;
}
};
Blue さんお世話になります
じっくり勉強させていただこうと思います。
先を越された。しかも寸分違わんとゆー orz
# ま、誰が書こうが大差ないよねー
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
struct count_ch {
map<char,int>& hist_;
count_ch(map<char,int>& hist) : hist_(hist) {}
void operator()(char ch) const { ++hist_[ch]; }
};
struct print {
void operator()(map<char,int>::value_type pair) const
{ cout << pair.first << ':' << pair.second << endl;}
};
int main() {
string data =
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz
;
map<char,int> hist;
for_each( data.begin(), data.end(), count_ch(hist));
for_each( hist.begin(), hist.end(), print());
}
επιστημη さん。ありがとうございます。
皆さんにいろいろ、教えて頂き感謝しております、そして興味がわきテストコードを
いろいろと書いているのですが、新たな疑問が湧き上がりました、別スレッドに
するのが懸命かと思いますが、この場をお借りすることをお赦しください。
質問
小文字を大文字に変換するコードをです。
vector コンテナをグローバル変数として宣言すれば、main 関数の中でも扱えますが、
main 関数の中。且つ、toUpper 構造体の外で宣言するとtoUpper 構造体の中では
参照できません、これはC++ の仕様なのでしょうか?もしそうであるならば、仕様が直感
的ではないように思えるのですが。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
//vector<char > vec; // グローバル変数ならOK
int main()
{
string data
=
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz
;
vector<char > vec; // ローカル変数にすると不可視?
struct toUpper {
vector<char >& _vec;
toUpper(vector<char >& vec) : _vec(vec) {}
void operator()(char ch) { vec.push_back(ch -= 0x20); }
};
for_each( data.begin(), data.end(), toUpper(vec));
struct show {
void operator()(char ch) { cout << ch << endl;}
};
for_each( vec.begin(), vec.end(), show() );
return 0;
}
すみませんでした、私の錯誤です。
コンストラクタが、参照を用いている理由を深く考えていませんでした。
toUpper(vector<char >& vec) : vec_(vec) {}
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string data
=
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccxyz
;
vector<char > vec;
struct toUpper {
vector<char >& vec_;
toUpper(vector<char >& vec) : vec_(vec) {}
void operator()(char ch) { vec_.push_back(ch -= 0x20); }
};
for_each( data.begin(), data.end(), toUpper(vec));
struct show {
void operator()(char ch) { cout << ch << endl;}
};
for_each( vec.begin(), vec.end(), show() );
return 0;
}