文字の出現回数 – プログラミング – Home

通知
すべてクリア

[解決済] 文字の出現回数


root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

よろしくです。
文字の出現回数をヒストグラムといいますか、文字種別に出現回数をカウントして
文字コード、出現回数をメンバにもつクラスに取得し。
更に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;
}


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

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


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

ありがとうございます
for_each( data.begin(), data.end(), [&](char ch) { ++hist[ch]; });
の [&](char ch) { ++hist[ch]; }
この部分は何をやっているのでしょうか?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

文字の出現回数を++してます。


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

重ね重ねありがとうございます。
なるほどmap pairの2番目を操作してるのですね
あと、どうしてもわからない部分なのですが、 [&](char ch)この部分の
[&] これは一体何でしょうか?\[&\] C++ とか検索するのですが、全く情報が出てきま
せん・・・
お分かりになる方教えてくださいませ。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

「ラムダ式」です。
http://codezine.jp/article/detail/4035


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

お世話になりました。ありがとうございました。


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

 お世話になります。もう一点教えて頂けないでしょうか
επιστημη さんに示していただいた、ラムダ式の方法ではなく
「関数オブジェクト」による書き方を教えて頂きたいのですが。
operator() を、このmap コンテナのどの部分に適用していいものか分りません。
よろしくお願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

こんなのしか思いつかなかった 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));


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

void でも動くのか。。。

struct hoge : public std::binary_function<char, map<char, int>*, void>
{
void operator()(char ch, map<char,int>* hist) const {
++(*hist)[ch];;
}
};


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

Blue さんお世話になります
じっくり勉強させていただこうと思います。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

先を越された。しかも寸分違わんとゆー 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());
}


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

επιστημη さん。ありがとうございます。
皆さんにいろいろ、教えて頂き感謝しております、そして興味がわきテストコードを
いろいろと書いているのですが、新たな疑問が湧き上がりました、別スレッドに
するのが懸命かと思いますが、この場をお借りすることをお赦しください。

質問
小文字を大文字に変換するコードをです。
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;
}


返信引用
root66
 root66
(@root66)
ゲスト
結合: 13年前
投稿: 10
Topic starter  

すみませんでした、私の錯誤です。
コンストラクタが、参照を用いている理由を深く考えていませんでした。
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;
}


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました