1 名前:858 [2007/12/24(月) 03:41:59 ] C++標準ライブラリの一つ、STLについて。 前スレ 【C++】STL(Standard Template Library)相談室 7 pc11.2ch.net/test/read.cgi/tech/1185986999/ 過去ログ・リンク・書籍紹介は >>2 以降
263 名前:デフォルトの名無しさん mailto:sage [2008/01/22(火) 01:36:14 ] >>262 重複を許そうが許すまいが、二分探索木はそもそもそういうものだろ 隣接した要素が木構造の上では離れた場所に置かれることがある イテレータをどうやって実装するのが普通かは知らないけど、setとmultisetで事情が変わる訳じゃない
264 名前:デフォルトの名無しさん mailto:sage [2008/01/22(火) 01:55:22 ] >>263 まったくもってそうでした。。。。 イテレータも、単にin-orderでtraverseすれば要素同士が離れていても問題なく連続して触ってくれますね。
265 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 10:22:33 ] COAP!
266 名前:デフォルトの名無しさん [2008/01/25(金) 08:16:31 ] COAPってナニ?
267 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 08:26:55 ] COAP=Containers of auto_ptr Effective STLぐらい買え
268 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 10:01:54 ] ありがとう
269 名前:デフォルトの名無しさん [2008/01/25(金) 15:47:58 ] struc foo { string name; }; std::vector<foo> v; foo *f = new foo; f->name = "ABC"; v.push_back( *f ); とやったときの、findでのABCの検索の仕方が全然解りません。 教えて下さい。
270 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 16:03:31 ] >>269 std::vector<foo>::iterator it = v.begin(); size_t pos = it->name.find("ABC"); あるいは size_t pos = v[0].name.find("ABC");
271 名前:269 mailto:sage [2008/01/25(金) 16:06:52 ] コードを端折ってすみません;; foo *f = new foo; f->name = "ABC"; v.push_back( *f ); の部分が何度も繰り返してる場合です。 for ( i = 0; i <100; i ++ ) { foo *f = new foo; f->name = IntToStr( i ); v.push_back( *f ); } とか。。
272 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 16:24:35 ] std::vector<foo>::iterator it; for(it=v.begin(); it != v.end(); it++) { if(0 == it->name.find("ABC")) { //hit } } こうかな? もしvの中に連続して文字列が存在していることを期待してて、 それをまとめてサーチしたいと思っているなら、各stringの中身は 別個に確保されてて繋がってないので無理じゃないかと。
273 名前:269 mailto:sage [2008/01/25(金) 16:33:03 ] なるほど。。なんかfind使う意味なさそうですね。 for ( int i = 0; i < v.size(); i ++ ) { if ( v[i].name == "もげもげ" ) puts( "一致" ); } でもいいわけですね。ありがとうございましt。
274 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 16:40:20 ] algorithmのfind()を使って探したいと言ってるのなら、 fooにoperator==を加えてnameとconst char*を比較できるようにするか、 find_if()に比較関数を渡すかすれば、 vector<foo>::iterator it = find(v.begin(), v.end(), "ABC"); こんな感じにも書ける。 <速度的な違いはほとんど無いと思うけど
275 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 16:48:42 ] もしstring.find()の検索効率を活用したいなら 文字列の格納先は単一のstringにして name.append(文字列); を繰り返してどんどん足していくしかないんじゃ。 で、足すときにnameの何バイト目は何個目の要素か ってなテーブルを同時に作って、findの結果から調べられる ようにしておくとか。
276 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 18:05:03 ] アルゴリズムの改良でSTLが使えないか質問です。 現在、キー文字列を与えると、それに応じた 文字列を返すSTL::mapのようなコードがあります。 ただ、返す文字列が可変です。例えば、キー"気温" を 与えると”今現在”の気温「5゚C」を文字列で返すと いった感じです。 現在このコードは ifとelseの連続で構成されたものと なっておりまして、効率面でも文字列比較を繰り返し 行っており、良いものではありません。 これを実現するのに、できればmapに似た簡単で効率の いい形で改良できないでしょうか?
277 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 18:18:02 ] >>276 すぐに思いつくのは文字列から「文字列を返す関数」へのマップだな "温度"を与えると「温度を計算する関数」が得られるようにする
278 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 18:19:08 ] >>276 map<string, string(*)(void*)> のような、キー文字列→関数のマップを作ればいいんじゃないかな
279 名前:278 mailto:sage [2008/01/25(金) 18:20:31 ] void*ってなんだろう・・・無視してくださひ。。
280 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 19:12:55 ] >>277-279 早速有難う御座います なるほど関数ポインタをマップですか。 確かに展望良さそうです。 早速コーディング検討したいと思います。 ありがとうございました!
281 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 23:18:56 ] >>273 今更だが、部分一致ならfind_ifを使う手もある。 #include <iostream> #include <string> #include <vector> #include <algorithm> #include <functional> struct foo { std::string name; }; struct FooNameIs : public std::binary_function<char *, foo, bool> { bool operator() (const char * match, const foo & f) const { return (f.name == match); } }; int main() { std::vector<foo> v; /* vに色々追加するコード*/ std::vector<foo>::iterator it = std::find_if(v.begin(), v.end(), std::bind1st(FooNameIs(), "ABC")); return 0; } あと、foo * f = new fooしてv.push_back(*f)してるのは、凄く気になる。
282 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 23:21:04 ] てか>>274 に書いてあったorz>>find_if
283 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 19:04:00 ] てかstringにsjis入れちゃだめでしょ
284 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 19:05:50 ] どこでSJISと特定したのか興味深い。
285 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:03:12 ] SJISだとしても、別に入れるのは問題ないだろ。
286 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:15:38 ] findとか使わなきゃね。
287 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:24:35 ] std::vectorとstd::basic_stringは分かれている必然性があんましない気がする
288 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:27:36 ] vectorのメモリ連続性が保証されなくなるのは嫌なので統合反対。
289 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:28:10 ] 次期 C++ だと string の連続性が保証されるよ。
290 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:47:37 ] んじゃ、char_traitsをvectorに入れると只のコンテナじゃ無くなるので統合反対。
291 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:49:36 ] c_str に触れればいいだけなような
292 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:58:58 ] >>287 統一してしまうとまずいことがあるよ。 vectorは末尾への要素追加のならし計算時間がO(1)じゃないといけないから、参照カウントによる copy-on-write最適化ができない。stringにはそういうしばりはないから、COWが可能。まぁ最近 はマルチスレッドの関係でCOWなstringは絶滅危惧種だけど。 他にもあったはずだが、とっさには思いつかない。
293 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:14:54 ] findしちゃだめって・・もう馬鹿かと。事実上利用不可だろ
294 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:16:36 ] そうは思わない。入れ物として使うなら十分。
295 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:20:07 ] c_str 使って外部の検索関数使えばいいだろ。
296 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:20:49 ] お前ら努力家だな
297 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:25:12 ] wstringのことも時々でいいから思(ry
298 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:25:43 ] wstring には SJIS なんて入れられないだろう・・・
299 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:26:03 ] wstringでSJISが正しく扱えるのかい。
300 名前:デフォルトの名無しさん [2008/01/27(日) 01:27:23 ] これだからWindowsしか知らない奴は。
301 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:31:02 ] stringは実用なんて論外としても、wstringもサロゲートあぼーんなわけで。。 もう文字列終わってるな
302 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:32:51 ] そこでUCS-4ですよ。
303 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:36:51 ] サロゲートあっても find に影響はないだろ?
304 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:37:18 ] wchar_t はその環境で扱える最大サイズの文字コードを入れる事ができるサイズであって UTF-16 だと決まってるわけでもないわけだが。実際4バイトの環境もあるし。 まあ、次期 C++ だと char16_t (UTF-16) や char32_t (UTF-32) が追加されるわけだが。
305 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:39:36 ] しかしwstringだと98系はもうだめだな。 クロスプラットフォームじゃないじゃんstl。。
306 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:40:32 ] クロス文字エンコーディングじゃないだけ。
307 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:40:52 ] >>303 UTF-8でもfindは問題ないからそのレベルでいいんだったらwstringを使う意味がない
308 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:41:38 ] >>304 それはビット幅だけじゃなくて中身もUTF-16/UTF-32であることが保証されてるの?
309 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:42:28 ] >>303 sizeがだめでしょ。
310 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:43:03 ] そんなもん中身を入れるコード次第だろ。
311 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:44:59 ] >>309 sizeは「か」に半濁点とかまで考慮するとUTF-32でもだめ
312 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:45:47 ] で、おまえらどうやってんの? string s = "abc"; // sjis!!。findとかしないで。。 wstring s = _T("abc"); // ウニコード。98とかでビルドしないで。サロゲートやばいかも どっちも地獄だな。CStringの方がましじゃね?
313 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:46:11 ] >>309 size は配列サイズが取得できれば十分じゃないか?
314 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:49:27 ] size()/length()はstrlenと等価だから。元々文字数を返すことを期待してはダメ。
315 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:50:00 ] だからIBMがアレを作ったのさ なんだっけアレ 眠くて思い出せない
316 名前:デフォルトの名無しさん [2008/01/27(日) 01:51:44 ] ICU
317 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:52:02 ] 集中治療室
318 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:54:11 ] >>308 Yes.
319 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:55:41 ] >>311 つか、ウニコード捨てればええだけの話しちゃうの? ウニコード捨ててもそんなにデメリットないような… … …
320 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:56:41 ] サロゲートはサブマリン的に最近問題に。。Unicode側は昔っから、 Utf-16はランダムアクセスはできない文字コードですよと言ってきたんだけど なんとなく流されて2バイトで便利みたいに扱われたり、たいていsizeは文字数を 返すとか説明されたり。。もう混乱の極み。 Javaとかはlengthは2バイト単位の長さを返す仕様に変わり、文字数の取得は codePointCountが追加されたりどの言語も苦肉の策を講じてる状態。 stlもなんとかしないといけない状況ではある。
321 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:58:34 ] >>320 日本語だけ扱ってる状況でサロゲートペア関係あるっけ
322 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:58:42 ] むしろ、stringをタダのコンテナに引きずり落とすくらいの意気込みで。
323 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:59:59 ] size が文字数返すなら、イテレータは1文字ずつ拾ってくる必要があるし、 そうなった時その型はどうするんだ? って話になる。 UTF-32 で合成があった場合とか、64ビット値を返すのか?
324 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:01:42 ] やっぱ速度の問題もあるし、javaみたいにsizeとcodePointCountの両方用意 しとくしかないんじゃないかなあと
325 名前:デフォルトの名無しさん [2008/01/27(日) 02:02:41 ] gccのwchat_tは32bitだから楽勝
326 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:04:33 ] >321 JIS2004と愉快な仲間たち。 >323 final はsizeいくつ、って話だよね。
327 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:05:42 ] >>325 サロゲートの文字数は取れない点は同じだけどね
328 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:07:28 ] イテレータだけじゃなくて [ ] も文字数に合わせた形にする必要がある。 でも、ランダムアクセスなんて無理じゃん?
329 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:09:46 ] world_char_tが定まるまで待ちましょう。
330 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:12:03 ] 結局ランダムアクセス用の冗長なデータを込みにしたクラスにしないとどうしようもないし、 パフォーマンス上そこまで標準に組み込まれることは無いだろう。 まあ、それ用のクラスを string 系列とは別に作ることは可能だろうが、 SJIS とかはまあ無理だな。
331 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:12:42 ] length(L"final")が5と帰ってきてくれたら、なにか嬉しい?
332 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:14:25 ] wstringのfind,insert,appendとかはサロゲートも平気そうな気がするけど なんとも微妙。。 文字とか文字数を意識した扱いをしようとしない限りは平気なのかな・・?
333 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:15:23 ] 文字数を指定しての置換とかはやばそうだな。
334 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:16:12 ] 非常によく使うデータ構造だから、効率を犠牲にして理想に走れないもどかしさ
335 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:16:41 ] findは大丈夫そうだけど、insert/appendは、サロゲートの前半だけ+別の文字、 みたいな不正な文字列を受け付けるべきか、みたいな話はあるよね。
336 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:17:18 ] 英語圏だとマルチバイトうぜーとかしか思われてないだろうしな。
337 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:18:12 ] stdc++のレベルで理想に走らなくても良いよ。というか理想がなんなのかも分からないし。この話題はこっち向きじゃないかい。 C++で新しい文字列クラスをつくろう 2 pc11.2ch.net/test/read.cgi/tech/1167132255/
338 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:20:06 ] 普通insertする文字とかiteratorもfindの結果のiteratorとかなわけで 問題なくね? >>333 確かに文字数指定でサロゲート文字の途中とかになってたら文字が切れちゃう よねぇ
339 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:21:08 ] もうこういうのは boost の領分かもしれないな。
340 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:21:41 ] がしがし書き換えたいならutf32に変換してから、書き換えて、utf8なりutf16なりに戻すほうが簡単そうだ。
341 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:24:29 ] 結局、find/appendなどの引数に与える文字が文字の途中などでない、 と文字数指定の関数に文字の途中などの数を指定しない を守ってればサロゲートもおけ、でいいのかな?
342 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:26:18 ] まぁあと15年位したら皆UTF-32でのんびりやってるさ
343 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:26:48 ] >>341 それを守るためにどれだけのコストが掛かるかって話してるんじゃないのか
344 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:27:16 ] >文字数指定の関数に文字の途中などの数を指定しない これを守るのがすげー大変そうだ。
345 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:27:59 ] まだSJISが使われてると思います><
346 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:28:55 ] SJIS 専用のクラスならまあ作れるだろうな。
347 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:29:01 ] 俺頭から5文字取るみたいなコードとりかえしがつかないくらい書いてるな
348 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:32:47 ] >>341 文字数ならサロゲートを割ってしまうことはないよ。 サロゲートペア一組で一文字だから。
349 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:33:58 ] wchar五個分でなくて、5「文字」分きちんと取れるコードを?
350 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:35:13 ] たとえば、 「か゛」は1文字という扱いでいいのか? 「か゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛(略」 みたいなどうしようもない連中はどうしよう?
351 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:38:26 ] >>348 std::string(wstring)の「文字数指定」は、1文字が固定長のコード体系が前提だから、サロゲがあると壊れるよ。 >>350 それペアになってなくない?
352 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:38:36 ] >>348 >サロゲートペア一組で一文字 一組で4バイト(結合文字は6バイトもある) で、文字数(というより2バイト単位)指定はアウト。 s = サロゲート文字列 s2 = s.substring(0, 5) とかやったらあぼーんでしょ
353 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:42:20 ] >>352 文字数というのは、キャラクタ数という意味で使った。
354 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:47:21 ] CString的にTCHAR使えてさらにクロスなものはないのかね?
355 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:48:52 ] >>350 合成文字は2キャラクタでしょ。 合成文字をぶった切ると、意味は通じなくなるかもしれないが違法ではない。
356 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:53:07 ] ああ、その「キャラクタ数」というのは、要するにUTF-32換算なわけか。
357 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 03:00:31 ] Winではstringは使うな。2バイト目が1バイト目とかぶってやがるからな。 wstringはサロゲートに注意して使え。途中で切るなよ。 Win98とかまだやってるカスはCStringでも使ってろ。 LinuxではstringでもEUCとUTF-8は2バイト目が1バイト目とかぶらないからまだ なんとかなるはずだ。 クロスにしたいなら文字列クラスは当然自前だろ? が俺の現状の認識
358 名前:デフォルトの名無しさん [2008/01/27(日) 03:02:31 ] >>327 ハァ?
359 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 03:09:34 ] >>358 へ?
360 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 03:14:40 ] >>357 追加でMac OS XはCFString使っとけ。以上。
361 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 04:50:39 ] >>357 OS 関係なくてエンコーディングの話だろ? Windows でも UTF-8 使えば問題ないし、 Linux でも Shift_JIS 使えば問題は出る。 クロスにしたければエンコーディングを OS 任せにしなければ良いだけの話。 たとえば UTF-8 を使うと決めれば std::string でもいけるでしょ。
362 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 05:05:46 ] >>361 だけの話・・って、実際にUTF-8でやったことないんだろ?試しにやってみなよ。 APIに渡すとき、コンソルに出すときすべてに変換をかます必要あるだろ? 文字リテラルはどうするんだ?ソース内のUTF-8はまだコンパイラのサポートが微妙だぞ。 現実的じゃないんだよ。OSが正式にサポートしてるSJISとかUTF-16以外を 内部エンコーディングにするのは。
363 名前:デフォルトの名無しさん [2008/01/27(日) 05:33:05 ] 1文字が何バイト使うかはどれ使っても一定ではない どれを使うか決まっていればどれ使ってもよい