[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 04/29 14:24 / Filesize : 158 KB / Number-of Response : 773
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【C++】STL(Standard Template Library)相談室 10



1 名前:デフォルトの名無しさん mailto:sage [2008/08/26(火) 12:01:17 ]
C++標準ライブラリの一つ、STLについて。

前スレ
【C++】STL(Standard Template Library)相談室 9
pc11.2ch.net/test/read.cgi/tech/1204045410/

過去ログ・リンク・書籍紹介は >>2 以降

139 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 13:30:52 ]
構文糖は重要だよ
各種LL言語が有用性を示してるじゃん

140 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 13:36:50 ]
イテレータとポインタは構文糖の関係にはない

141 名前:デフォルトの名無しさん [2008/10/22(水) 19:03:29 ]
>>137
typedef 一回書けば解決

142 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 21:04:19 ]
double型 と char型のメンバを持つ構造体をvectorにいれて、全要素入れ終わったらソートみたいにしてるんですけど、

mapとかつかったらもっと効率よくなりますか?ソートするキーはdouble型の値で、降順です。

143 名前:デフォルトの名無しさん [2008/10/22(水) 21:30:53 ]
ファイルからや手からの入力ならset使えば、ソート時間はほぼ無い。
読み込んでいる間にソートされるので。
もしメモリ間の転送であっても速いとは思う

144 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 21:40:54 ]
mapじゃなくてpairかもしれません。

pairでdouble型とchar型のメンバを作って、doubleをキーにソートって感じにしたいんですが、どうしたらいいですか?
char型のメンバは重複する場合もあります。

145 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 21:46:00 ]
扱う要素数によるよ。
整数とかポインタなら、数千まではvectorの方が一般的に他のコンテナよりも速い

146 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 21:49:31 ]
つまりvectorにガシガシいれてあとからソートですか?

147 名前:デフォルトの名無しさん [2008/10/22(水) 21:50:32 ]
実測しよう



148 名前:デフォルトの名無しさん [2008/10/22(水) 21:51:29 ]
それほど速度を気にしないなら、setにぶち込むのが簡単。 いれたらソート終わっているので

149 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 21:52:15 ]
そんなに速度は気にしません。あまりにも比較して遅いなら別ですが

150 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:02:12 ]
気になるなら測れ、としか。

151 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:03:05 ]
速度気にしてないのか

152 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:13:56 ]
気にしてないわけではありません。
実測してみます

153 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:18:40 ]
typedef struct{

double dist;

char name[20];

}DIST;


int main(){

std::set<DIST> distance;

distance.insert( 200 ); →2要素を代入するにはどうすればいいですか?


}

154 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:22:03 ]
>>153
DIST型のオブジェクトを渡すべきところへ200を渡してどーすんですか

155 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:36:25 ]
あらかじめvectorでサイズを決め打ちするなら早いけど、
領域を増やしていくならsetのほうがはやい

156 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:37:13 ]
>>154
渡し方がわかりません。ソートに使うキーはdoubleのほうです

157 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:40:53 ]
>>153
std::pairでくるんで渡せ



158 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:54:03 ]
こんなんでどう?

struct DIST {
double dist;
char name[20];
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}
friend class Comp;
};

struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};

int main()
{
std::set<DIST, Comp> distance;
distance.insert(DIST(200, "abc")); //→2要素を代入するにはどうすればいいですか?
distance.insert(DIST(100, "def"));
distance.insert(DIST( 50, "ghi"));

for (std::set<DIST, Comp>::const_iterator pos = distance.begin(); pos != distance.end(); ++pos)
std::cout << pos->dist << ", \"" << pos->name << "\"\n";
}

159 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:54:46 ]
distance.insert( std::pair(200.0 ,"moziretu") );
こうですか?

160 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:56:05 ]
>>158
通りません・・・

161 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 22:56:51 ]
>>160
これ頭に付けてるよな

#include <iostream>
#include <cstring>
#include <set>

162 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 23:02:07 ]
>>161
コピペみすってました・・・

struct DIST {
double dist;
char name[20];
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}

friend class Comp;
};

struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};

これがどういうことをしてるのかわかりません。

163 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 23:07:19 ]
>>162
まず二要素を一度に代入できるように、DISTにコンストラクタを付けた。
こうする事によって一時オブジェクトが生成できるようになる。

次にソートの基準をdoubleにするために、叙述関数もしくは関数オブジェクト
を書かなければならないが、この場合は関数オブジェクトを書いている。

というのもstd::setのデフォルトの比較基準はless<DIST>となり、これは
存在しないので、自分で書かなければならないからだ。そこで比較関数
オブジェクトにCompを使う事にして自分で書いている。

164 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 23:09:37 ]
classがstructになっててなんかおかしいよ

165 名前:デフォルトの名無しさん mailto:sage [2008/10/22(水) 23:20:44 ]
>>164 わかったよこれでいいだろ
class DIST {
double dist;
char name[20];
public:
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}
double getdist() const {
return dist;
}
const char* getname() const {
return name;
}
friend class Comp;
};
struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};
int main()
{
std::set<DIST, Comp> distance;

distance.insert(DIST(200, "abc")); //→2要素を代入するにはどうすればいいですか?
distance.insert(DIST(100, "def"));
distance.insert(DIST( 50, "ghi"));

for (std::set<DIST, Comp>::const_iterator pos = distance.begin(); pos != distance.end(); ++pos)
std::cout << pos->getdist() << ", \"" << pos->getname() << "\"\n";
}

166 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 02:37:33 ]
おまえら暇だな…

DIST dist;
distance.insert(dist);

167 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 19:19:10 ]
func(string hoge){

}
という関数に

char mozi[256];で宣言された文字列をfunc(mozi)みたいに渡せますか?



168 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 19:20:02 ]
ええ

169 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 19:21:30 ]
なんでそんなことができるんですか?

170 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 19:23:21 ]
stringのコンストラクタにconst char*を取るものがあるから

171 名前:デフォルトの名無しさん mailto:sage [2008/10/23(木) 19:26:39 ]
なるほど!STLってほんとにすごいですね

172 名前:デフォルトの名無しさん mailto:sage [2008/10/24(金) 00:21:21 ]
でもSTL関係ないですね!

173 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 03:20:25 ]
stringはSTLだろ
basic_string<char>でテンプレートだし。

174 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 04:09:49 ]
>>173
馬鹿発見

175 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 08:24:14 ]
>>173
ん・・あぁ・・そうだね・・・・

176 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 10:01:54 ]
>>173
const char *を引数にとるコンストラクタを持つ文字列クラスは、STL固有ではありません。

177 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 17:43:47 ]
んなこたーない



178 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 18:02:21 ]
自前で似たようなモノを作れるのに?

179 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 18:47:47 ]
>>176
const T* だよ

>>178
STLであろうがなかろうが全部自前で似たようなものを作れるぞ

180 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 20:47:06 ]
なんか話が噛み合ってない

181 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 21:03:12 ]
わかってないんだよ、おそらく本当にw

182 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 21:23:12 ]
ということにしたいのですね。

183 名前:デフォルトの名無しさん mailto:sage [2008/10/25(土) 21:36:55 ]
はいはい模範回答。

もともとのAlexanderのSTLにはbasic_string<>は無かった。
しかし、標準化の過程でSTLコンテナに適合するようにされた。

basic_string<>がalgorithmと重複するようなメンバ関数を持っていたり、
しかもそれがイテレータではなくsize_typeを扱ったりするのはその名残。

184 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 10:23:42 ]
>>173 の
>basic_string<char>でテンプレートだし。
てのが気になるなあ…
「stream I/O もテンプレートだからSTL」とか言い出しかねない勢い。

185 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 12:46:36 ]
入念に勉強してない限り、
「C++コンパイラに付いてくるtemplate classを使ったもの全部=STL」
と思っている人は多い気がする
実用上困る事項でもないし・・・

186 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 15:08:26 ]
定期的に出る話題だから
今回も「ああ、またですか」てなもんだ。
でもbasic_stringはもう
仲間に入れてあげてもいいと思うんだ。

187 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 16:00:31 ]
やだよ
basic_stringなんてC++標準化委員会も「失敗作だった」と
認めているじゃないか



188 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 20:21:30 ]
そこまで言ってたっけ。

189 名前:デフォルトの名無しさん mailto:sage [2008/10/27(月) 20:55:00 ]
>>186
たまにこのスレを斜め読みするものとしては
そういう話が定期的に回ってくれると
自身の無知加減がよくわかるから助かるよ。

basic_stringって曰くがあったのか・・・(´・ω・)

190 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 01:35:54 ]
>>187 ソースくれ

191 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 01:47:14 ]
標準化委員会はSTL自体が「失敗作だった」って
認めてたぞ

192 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 01:50:21 ]
標準化委員会はC++自体が「失敗作だった」って
認めてたぞ

193 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 04:45:29 ]
親は>>192自体が「失敗作だった」って
認めてたぞ

194 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 11:11:11 ]
俺は「性交作だ」って聞いた

195 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 11:40:21 ]
おあとがよろしいようで

196 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 20:20:17 ]
100個ぐらいの文字列を入れて
そのなかで一番出現率が高い文字列を探すには
STLのどんなデータ構造とアルゴリズムをつかえばいいでしょうか?

197 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 20:43:38 ]
まず服を脱ぎます



198 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 20:44:07 ]
次にソートします

199 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 20:48:02 ]
かぜひきました

200 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 20:51:58 ]
相当大変な事態ですね。

201 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 21:02:46 ]
手術は成功です

202 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 21:25:40 ]
そーっとしておいてくださいね

203 名前:デフォルトの名無しさん [2008/10/28(火) 21:27:19 ]
真面目な解答お願いします

204 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 21:32:40 ]
std::map<string,int>で出現頻度数えれば?


205 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 21:36:06 ]
質問です。

struct a {
func() {}
};

struct b {
vector <a> va:
};

とあって、for_eachアルゴリズムでva内のfuncを呼び出すには
どのような書き方をすればいいのでしょうか?mem_fun_refと
bind2ndを組み合わせるのでしょうか?

206 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 21:44:53 ]
自己解決しました。mem_fun_refだけでいいようです。

207 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:11:52 ]
>>204
連想配列ですよね?stringがキーでintが値ってことですか?



208 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:14:09 ]
hash


209 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:17:42 ]
map<string,int> mとすると、m[str]++としてあとはソートなりなんなりすりゃいい

210 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:30:23 ]

map<string,int> test;

test["hoge"]++;

sort(test.begin(), test.end(), greater<int>());

こうですか?


211 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:40:03 ]
mapってソートできないだろ
挿入した時点でキーで自動的にソートされてるんだから

全部要素を挿入したらvectorにでも全要素をコピーして
今度はint基準でソートすればよい

212 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:41:26 ]
なるほど。どうりでコンパイルが・・・
ちょっとやってみます

213 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:43:39 ]
vectorにキーと値の構造体をコピーするんでしょうか?

最大値を知りたいのではなく、最大値をとるキーをしりたいんです

214 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:51:17 ]
脳味噌を使え脳味噌

215 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:55:46 ]
何か汚ねえなあ・・・lambdaを使わないとやっぱ綺麗に書けんわ

struct Comp : public std::binary_function<std::pair<std::string, int>, std::pair<std::string, int>, bool> {
bool operator()(const std::pair<std::string, int>& v1, const std::pair<std::string, int>& v2) const {
return v1.second < v2.second;
}
};

void print(const std::pair<std::string, int>& v)
{
std::cout << "string = '" << v.first << "', count = " << v.second << std::endl;
}

int main()
{
std::map<std::string, int> msi;
std::vector<std::pair<std::string, int> > vsi;

msi["abc"]++; msi["abc"]++; msi["abc"]++; msi["abc"]++; msi["abc"]++;
msi["def"]++; msi["def"]++;
msi["ghi"]++; msi["ghi"]++; msi["ghi"]++; msi["ghi"]++;

for (std::map<std::string, int>::iterator pos = msi.begin(); pos != msi.end(); ++pos)
vsi.push_back(std::make_pair(pos->first, pos->second));

std::sort(vsi.begin(), vsi.end(), Comp());
std::for_each(vsi.begin(), vsi.end(), print);
}

216 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:58:14 ]
わざわざmapにするいみあんの?

217 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 22:59:29 ]
なんか複雑ですね・・・
ちょっと解読してみます



218 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:01:17 ]
>>216
挿入が楽
それだけ

219 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:03:53 ]
ああ強いて言えば挿入が速いか・・・

220 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:04:51 ]
「一番」出現頻度高いのが欲しいだけなら、わざわざソートまでする必要なかろ
O(n)で済むぞ


221 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:05:45 ]
>>220
えっとどうするんですか?

222 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:07:06 ]
mapに突っ込んだ後で、単に全舐めすりゃいいだろ
シークエンスの最大値を求めるのにいちいちソートするのか?お前さんは

223 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:09:36 ]
まあそうだな
イテレータを回すだけ
最大値が知りたいだけならそれでいい

224 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:11:33 ]
まあただ最大値の文字列の候補が複数あった時は少々工夫が必要か

225 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:12:10 ]
最大値にタイがある場合も考慮せにゃならんな
単純でいて意外と深いのかもしれないw

226 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:17:42 ]
int main(){

string str;

map<string,int> test;

int maxval=0;
int maxkey;

test["hoge"]++;
test["hoge"]++;
test["huga"]++;

map<string, int>::iterator itr = test.begin();
map<string, int>::iterator itrEnd = test.end();



while(itr != itrEnd){

      itr++;
}


}

こうしたんですが、値自体はどうやって参照するんですか?

227 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:21:00 ]
itr->second



228 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:23:12 ]
ああそうかpairのコンテナなんですよね

229 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:25:51 ]

int main(){

string str;

map<string,int> test;

int maxval=0;
string maxkey='\0';

test["hoge"]++;
test["hoge"]++;
test["huga"]++;

map<string, int>::iterator itr = test.begin();
map<string, int>::iterator itrEnd = test.end();



while(itr != itrEnd){
if(itr->second >maxval){
maxval = itr->second;
maxkey = itr->first;
}
itr++;
}

cout << "maxkey:" << maxkey << endl;

}
コンパイルはできるんですが、とまります・・・

230 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:27:09 ]
>>224-225
そうなんですよね。その辺は工夫でできそうです


231 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:29:41 ]
タイを考慮しても2回舐めればいいだけだから、たいした問題ではないか
なんちって

232 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:30:49 ]
タイがあっても3つ以上はことはないとおもうんで、大丈夫そうです。

しかし動かないです・・・

233 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:34:12 ]
>>229
>string maxkey='\0';

が良くない。これはstring maxkey=NULL; と同じ意味になる。
つまりアドレス0をアクセスする文字列で初期化しようとする。

234 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:35:44 ]
基本からやった方がいいんじゃ・・・

235 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:37:58 ]
>>233
if文内で代入するので問題ないかと思ったんですが・・・

>つまりアドレス0をアクセスする文字列で初期化しようとする。
??

236 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:38:35 ]
微妙に誤解を招きそうなので訂正

×つまりアドレス0をアクセスする文字列で初期化しようとする。
○つまりアドレス0から始まるC文字列で初期化しようとする。

処理系によっては文字列が大きすぎて止まり、他の処理系では
アドレス0をアクセスするのでセグメントエラーで止まったりする。

237 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:39:17 ]
正しくはstring maxkey=""; あるいは単にstring maxkey でいい。



238 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:40:39 ]
>>235
charだけを引数に取るコンストラクタがないため、
暗黙の変換でconst char*を引数に取るコンストラクタが呼ばれてしまう。

239 名前:デフォルトの名無しさん mailto:sage [2008/10/28(火) 23:40:40 ]
わかりました。親切にありがとうございました






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<158KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef