【C++】STL(Standard ..
159:デフォルトの名無しさん
08/01/13 22:13:59
>>156
KeyとValueの両方の条件で削除要素を決定するなら
汎用性を考えた場合、Linerになるけど全部舐める
しかないかもな。まあ、今の場合は削除対象を絞る
条件がKeyが3に固定されてるからいいけど。
160:デフォルトの名無しさん
08/01/13 23:31:50
>>156
149の通りの条件なら、Key == 3 の範囲をequal_rangeで得て、
その範囲に対して Value == 'c' を消してまわるのが速そう。平均的には、ね。
総要素数に対してequal_rangeの範囲が無視できるだけ小さいならおk。
実際に行いたい条件が149と違う場合は話が違ってくる。
Keyが単一とは限らないとか。...って、>>159に書いてあるか。
161:デフォルトの名無しさん
08/01/14 10:47:18
そういえばmultimapってどういう用途に使ってますか?
mapは連想配列の様に便利に使ってますが
multimapという道具の使い方がいまいち思い浮かばない…。
162:デフォルトの名無しさん
08/01/14 11:02:35
得点が0〜100点で、名前を要素とする
同一得点は存在するからマルチ
163:161
08/01/14 11:07:45
>>162
なる。 70点取った人を羅列その他できますね。 サンクスです
164:デフォルトの名無しさん
08/01/14 11:23:23
>>161
辞書
165:デフォルトの名無しさん
08/01/14 11:25:39
STL限定なら別だけど辞書ならbimapの方がよくね?
166:デフォルトの名無しさん
08/01/14 11:48:17
用途の話しだ
167:デフォルトの名無しさん
08/01/14 13:18:36
「ようとのはなししだ」ですか?
168:デフォルトの名無しさん
08/01/14 13:19:33
>>167
辞書引け
169:デフォルトの名無しさん
08/01/14 13:19:40
とりあえず度数分布表以外にも例挙げてよよよ
170:デフォルトの名無しさん
08/01/14 13:21:26
>>168
辞書ならbimapの方がよくね?
171:デフォルトの名無しさん
08/01/14 13:22:53
用途の話だ。
172:デフォルトの名無しさん
08/01/14 16:46:33
>>162
この例で、0点のダメ男君が何人いるかと、
その名前の列記とかってどうやって出力するの?
mismatch()とか使うのかな。
foreachループでフラグ立てながらは勘弁
173:デフォルトの名無しさん
08/01/14 16:59:41
俺ならequal_range
174:デフォルトの名無しさん
08/01/15 02:04:41
割と典型的なequal_rangeの出番だと思う。
人数だけが知りたい場合は、countがいいかな。もちろんメンバ関数のほうね。
175:172
08/01/15 11:07:03
>>173-174
ありがとうございます。 equal_range、及びcount便利ですね。
説明読んでて、「該当者のいる得点一覧」(無重複の使用キー一覧)の方法に
ぶちあたった。 もうちょい調べてみます。
176:デフォルトの名無しさん
08/01/17 18:02:56
配列の先頭を指すポインタと末尾を指すポインタのペアを返す
テンプレート関数を作成したいのですが、うまくいきません。
以下のコードはVC++6.0でもBCC5.5でもコンパイルエラーです。
正しい方法を教えてください。
#include <utility>
#include <algorithm>
template <class T, int n>
std::pair<T*, T*> iseq(T a[n])
{
return std::pair<T*, T*>(a, a + n);
}
int main()
{
int x[] = {6, 1, 3, 4, 2};
std::sort(iseq(x).first, iseq(x).second);
return 0;
}
177:デフォルトの名無しさん
08/01/17 18:07:47
VC6やBCC5といった糞コンパイラを捨てる
178:デフォルトの名無しさん
08/01/17 18:09:45
>>176
#include <utility>
#include <algorithm>
#include <iostream>
#include <iterator>
template <class T, int n>
std::pair<T*, T*> iseq(T (&a)[n])
{
return std::pair<T*, T*>(a, a + n);
}
int main()
{
int x[] = {6, 1, 3, 4, 2};
std::sort(iseq(x).first, iseq(x).second);
std::copy(x, x + sizeof(x) / sizeof(x[0]), std::ostream_iterator<int>(std::cout, " "));
}
179:デフォルトの名無しさん
08/01/17 18:13:54
ああそうだわ、>>178はBCCじゃコンパイルできないよ。
VC6はどうか知らんが、VC7.1やVC8、VC9なら行けると思う。
gcc3.4.5でもOKだった。
180:デフォルトの名無しさん
08/01/17 18:16:29
>>179
bcc5.5.1と5.8.2でコンパイルできたよ
181:デフォルトの名無しさん
08/01/17 18:17:41
BCC5.9.2でも行けるね。
182:176
08/01/17 18:25:31
>>178
ありがとうございます。>>180さんがおっしゃるとおり
bcc5.5.1ではOKでしたが、VC++6.0ではダメでした。
183:デフォルトの名無しさん
08/01/17 18:52:19
boost::begin()やboost::end()の実装を参考にしてみれば?
184:デフォルトの名無しさん
08/01/17 22:40:09
>>178がコンパイルできないのは、どこが原因?
185:デフォルトの名無しさん
08/01/17 22:44:49
>>184
iseq(T (&a)[n])
この部分が解析できないフロントエンドを持つコンパイラ。
186:デフォルトの名無しさん
08/01/17 23:06:23
VC6 とか無理だった記憶がある。
187:デフォルトの名無しさん
08/01/17 23:47:01
>>185
T (&a)[n] の仮引数aの型が解らんてこと?
aが配列参照と理解できないってことかな
188:デフォルトの名無しさん
08/01/17 23:59:29
配列参照に対応していないだけ。
189:デフォルトの名無しさん
08/01/18 00:54:28
BCCは template で T (&a)[n]とやってあると大丈夫みたいだが
int (&a)[n] のように型を決め打ちされてしまうとコンパイルが
通らなかったような。
templateの特殊化には対応してんのかな。どっかいろんな細かい
部分が標準と挙動が異なるのでSTLportから見捨てられかけたり
boostへの対応度が低かったりする。
190:デフォルトの名無しさん
08/01/18 08:37:20
コンパイラ実装者にとってパターンマッチほど面倒くさいものはない。
191:デフォルトの名無しさん
08/01/18 09:13:16
VC6 はもうそろそろ寝かせてやって,
VC9 使おうよ… Express Edition もあるんだから.
192:デフォルトの名無しさん
08/01/18 09:14:58
VC9も色々バグがあってヤヴァイみたいだけどな
STLをやboostを使うならVC8がgccとかも含めて一番安定して使えるかも
193:デフォルトの名無しさん
08/01/18 09:35:46
質問です。
equal_range()でvectorの特定の値を検索したいのですが
vectorの要素はマルチキーなのです。
typedef struct{
int x;
int y;
}DATA;
このような感じの場合。
どのようにすればいいのでしょうか?
やはり自分で作らないと出来ないのでしょうか?
宜しくお願いします。
194:193
08/01/18 10:30:48
事故解決しました。
第4引数があるんですね・・・。
でもこの引数、ググっても、日本語のページは、4件しかヒットしないや・・・orz
195:デフォルトの名無しさん
08/01/18 10:31:00
boost使うなら現状VC8の方がいいだろうが
それ以外バグが問題でVC8使った方がいい
ってあり得るの?
196:デフォルトの名無しさん
08/01/18 13:53:30
>>194
STLはそういう使い方しないもん。
structじゃなくて、classにしとけよ。
operator定義できないから、多分比較関数定義出来ないぞ。
検索する値はint型、比較する対象はvector<DATA>のDATAっしょ?
比較関数は定義できても、呼び出し側の引数は等価な型を与えるから無理。
先に比較用のoperator書かないと。
197:デフォルトの名無しさん
08/01/18 14:07:07
structかclassかの問題だったのか
198:デフォルトの名無しさん
08/01/18 14:21:50
>>196
別にstructでもoperator()は定義できるでしょ。
今はそれはどうでもよくて、strict weak odering条件を満たす
bool operator(const Data&, const Data&);
を定義して、operator(const Data&, const Data&)で
vector<Data>をソートしておいて、eqaul_rangeに同じ
Comparisonであるoperator(const Data&, const Data&)を
渡せばいいんでないのか?
ということを>>193は言ってると思ったんだが。
199:デフォルトの名無しさん
08/01/18 14:30:05
× bool operator(const Data&, const Data&);
○ bool operator<(const Data&, const Data&);
200:デフォルトの名無しさん
08/01/18 14:46:28
>>198
operator<を定義してたらComparison(>>194の言う第4引数)渡さなくていいんじゃ?
201:デフォルトの名無しさん
08/01/18 15:12:36
あれ?structでoperator定義出来たんだ。
202:デフォルトの名無しさん
08/01/18 15:18:21
>>200
クラスのメンバーとして定義するなら、そうだね
>>201
structとclassの違いはデフォルトのアクセスレベルだけでしょ。
203:200
08/01/18 16:00:31
>>202
なるほど、>>198の言ってることがようやく解った
204:デフォルトの名無しさん
08/01/19 14:15:43
↓って同一?マングル名とかも含めて。
struct xxx {
xxx();
private:
int n;
};
class xxx {
int n;
public:
xxx();
}
205:デフォルトの名無しさん
08/01/19 14:40:30
class はテンプレート仮引数の型として使えるが、struct は使えない、という違いもなくはない。
206:デフォルトの名無しさん
08/01/19 14:44:14
>>205
お、ほんとだ。知らなかった。何か理由あるのかね。
207:デフォルトの名無しさん
08/01/19 14:48:53
typenameでいいじゃない
208:デフォルトの名無しさん
08/01/19 14:49:26
テンプレート仮引数のclassとクラス宣言のclassって意味が違うんじゃないの。
仮引数のclassは型名を表すだけで、そこにclass入れようがstruct入れようが組み込み型入れようが構わないんだから。
209:デフォルトの名無しさん
08/01/19 14:51:53
クラステンプレートを引数にとるときは class しか使えないね。
210:デフォルトの名無しさん
08/01/19 14:57:54
classを使わずにstructを使うメリットって何?
コンストラクタ定義しなくても、メモリサイズ的に変わったりするの?
211:デフォルトの名無しさん
08/01/19 14:59:21
簡単なデータの塊を表現する時に struct を使ってる。
struct Point3d { double x, y, z; }; とか。
212:デフォルトの名無しさん
08/01/19 15:01:34
構造を保ったままCとインタフェースできる。
213:デフォルトの名無しさん
08/01/19 15:11:54
template <template<typename T> class C> //OK
template <template<typename T> struct C> //NG
214:デフォルトの名無しさん
08/01/19 15:19:24
template <template<typename T> typename C> //NG
これも書いておかないと片手落ちだ
215:デフォルトの名無しさん
08/01/19 16:16:28
>>214
それは常識すぎる。
216:デフォルトの名無しさん
08/01/20 23:29:14
fwrite()でvector<int> vの中身を一気に書き出したいのですが
効率の良い方法はないのでしょうか?
vector<int> v;
fwrite(v, sizeof(int), v.size(), fp);
のような感じで一気に書き出せれば凄くうれしいのですが
これではエラーになります。定義されているoperatorがうまくintのポインタの代わりをしてくれるかと思ったのですが
どうやら無理のようです。
これは、一度個数分ループまわしてintに書き出さないとダメなのでしょうか?
217:デフォルトの名無しさん
08/01/20 23:33:38
&v[0]
218:デフォルトの名無しさん
08/01/20 23:39:03
あるいは &v.front()
好きな方を使え。
次期 C++ だと v.data() で良くなるみたいだが・・・
まだないものは仕方が無い
219:デフォルトの名無しさん
08/01/21 00:14:53
>>216
ofstream ofs;
と
copy(v.begin(), v.end(), ostream_iterator<int>(ofs, " "));
とかではダメなんか?
220:デフォルトの名無しさん
08/01/21 00:43:42
fwriteだからバイナリで書きたいんだろ
221:デフォルトの名無しさん
08/01/21 01:07:58
>>220
じゃあostreambuf_iterator使えば?
222:デフォルトの名無しさん
08/01/21 06:41:18
コンテナの中が連続して配置されていることが
保障されているのはvector だけ?
って,list とかでそんなことできるわけないよな.
223:デフォルトの名無しさん
08/01/21 06:55:51
vectorはC配列との互換性のためにわざわざそんな保証をしてるわけですから
224:デフォルトの名無しさん
08/01/21 08:23:25
そのために無駄なコピーが発生しまくり
225:デフォルトの名無しさん
08/01/21 10:31:26
std::ifstream fin( "in.bat", ios::binary );
std::ofstream fout( "out.bat", ios::binary );
std::copy(
std::istreambuf_iterator<char>( fin ),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>( fout ) );
このコードって超おせーんだけど、なんで??
226:デフォルトの名無しさん
08/01/21 12:18:26
>>225
それだとディスク内のin.datにアクセス→ディスク内のout.datにアクセスを何度も繰り返すから、
in.datのデータを一度数キロバイトのバッファに入れてからまとめてout.datに書き込んで
ディスクへのアクセスを減らした方が早いよ。
環境にもよるけど、一度ディスクにアクセスする間にメモリからデータを十万回程度アクセスできる。
読み込みも書き込みもまとめてディスクへアクセスすればシーク時間も節約できる。
227:225
08/01/21 13:30:36
>>226
iterator を使うと、fstream へのアクセスが 1 文字ごとに
なっちゃうっていう理解でいいですか?
なんとなく iterator のほうがカッコいいかなって思ったんだけど、
使い物にならんほど遅いので…。
素直に
fstream::read()
fstream::write()
を使えということでFA?
228:デフォルトの名無しさん
08/01/21 14:20:07
つ streambuf_iterator
229:デフォルトの名無しさん
08/01/21 14:58:03
>>228
俺には>>225のコードがstreambuf_iteratorを使っているように見えるんだが。
230:デフォルトの名無しさん
08/01/21 15:10:47
吊ってくる…
231:デフォルトの名無しさん
08/01/21 15:26:30
低レベル(遅延書き出しなど)でのディスク書き出しはOSの機能
だと思われ。書き出すタイミングも。
streambuf_iteratorを使う(内部的にsgetc, sbumpc, sputcを
使ってる)ということはプログラムレベルでのストリームバッファ
を直接操作してるわけで、ファイルストリームオブジェクトに対して
read、writeを使うと非バッファ操作になるから速くなることは
ないと思える。実測次第だな。
OSのチューニングなりドライバこさえるなりするのも一考。
232:デフォルトの名無しさん
08/01/21 19:53:04
これで速くなるのかな
URLリンク(itpro.nikkeibp.co.jp)
233:デフォルトの名無しさん
08/01/21 19:55:10
最新のドラフトを見ると string も連続性を保証するようになるっぽい。
234:225
08/01/21 19:58:24
>>231
う〜ん・・・
boost::timer t;
for( int i=0; i < 10; ++i ) {
ifstream fin( "in.dat", ios::binary );
ofstream fout( "out.dat", ios::binary );
copy (
istreambuf_iterator<char>( fin ),
istreambuf_iterator<char>(),
ostreambuf_iterator<char>( fout )
);
}
cout << "iterator=" << t.elapsed() << endl;
t.restart();
for( int i=0; i < 10; ++i ) {
ifstream fin( "in.dat", ios::binary );
ofstream fout( "out.dat", ios::binary );
while( !fin.eof() ) {
char buf[BUFSIZ];
fin.read( buf, BUFSIZ );
fout.write( buf, BUFSIZ );
}
}
cout << "read_write=" << t.elapsed() << endl;
のコードでやったら、iterator=2.093, read_write=0.438で、5倍ほど差がつきました。
環境は WinXP + VC8 です。
まぁ、どうしても iterator 使いたいわけじゃないので、おとなしくread() と write() 使います。
235:デフォルトの名無しさん
08/01/21 20:54:05
multisetの実装について教えてください。
値の重複を許す二分探索木というのは、どう構成したらいいのかよくわかりません。たとえば、
10
8 12
みたいなところ(10がルートで8と12が左右の子)にもうひとつ10を挿入すると、どういう木になるんでしょうか?
red-black treeでなく、単なる二分探索木の話でよいので教えてください。
236:デフォルトの名無しさん
08/01/21 21:34:55
>>234
やっぱりディスクアクセスが頻発するのか。
streambuf_iteratorはstream_iteratorに比べると速いというだけか。
ただ、そのプログラムのread/writeだと正しくファイルがコピーされなかった。
おそらく、fout << fin.rdbuf(); 一行で正しくコピーできると思う。
by VC++ 2008
237:デフォルトの名無しさん
08/01/21 21:39:20
>>234
fout.write( buf, BUFSIZ );
がコピーできない原因か。BUFSIZEのゴミまでコピーされてしまう。
238:デフォルトの名無しさん
08/01/21 21:56:13
flushみたいな名前の
239:225
08/01/21 22:20:19
おお、ほんとだ。
こんな単純なミスをするとはww
ファイルのサイズがBUFSIZの倍数になってたから
正常に動いてるように見えてたみたい
>>236
書き方は rdbuf() が一番簡単ですね。
さっきのコードで
fout << rdbuf();
と
char buf[BUFSIZ];
fin.read( buf, BUFSIZ );
int n = fin.gcount();
fout.write( buf, n );
でやってみましたが(他の部分は同じ)、
rdbuf=1.375
read_write=0.406
で、速度を気にする場合は read(), write() のほうが早いようです。
簡潔に書きたいときは
rdbuf()
速度が重要な時は
read(), write()
を使う方向でいこうと思います。
240:デフォルトの名無しさん
08/01/21 22:23:42
>>232
あほうすぎる話だなw
こんなのDBの研究者が聞いたら鼻で笑っちまうぜ。
挙句の果てVBかよw
241:デフォルトの名無しさん
08/01/21 22:29:51
/.J でもさんざん馬鹿にされてる
242:デフォルトの名無しさん
08/01/21 22:30:27
>>239
そうrdbufだと結構遅かったんだよね。
gcount()があったんだ。それ使ったほうが良いよ。
速いに越したことはない。
thx。色々参考になったよ。
243:デフォルトの名無しさん
08/01/21 22:32:50
>>240
DBの検索アルゴリズムはよく知らんが、
アルゴリズムを考えるときに言語使用は関係ないだろ。
それに、どうせ使ってるのはOSのAPIだろうから、VBだろうが、Cだろうが、
呼び出す速度は同じじゃね?
244:デフォルトの名無しさん
08/01/21 22:40:10
「OSの基本機能であるファイル名の検索機能」とやらのアルゴリズムを
そっくりそのままDBに応用しようとは考えなかったんだろうか??
245:デフォルトの名無しさん
08/01/21 23:05:24
STLの配列にクラスのポインタを入れて使用したいのですけど、
そのようなことって可能なのでしょうか?
246:デフォルトの名無しさん
08/01/21 23:09:31
>>245
コピーしたときに問題がおきるからだめ
たとえば、
class my_class;
vector<my_class*> v1;
vector<my_class*> v2 = v1;
だと、v1とv2の指してる先が同じになっちゃう。
ポインタが(というか、newが)使いたいなら、boost::shared_ptr 使って
入れろ。
boost::shared_ptr でググって、使い方がわからんなら
STLコンテナにポインタ入れるのはあきらめろ。
247:デフォルトの名無しさん
08/01/21 23:10:38
>>245
配列?valarray?
ちなみにコンテナだったら可能だよ。
まあ色々面倒だからスマートポインタ使うか
boostのpointer containerとか。
248:デフォルトの名無しさん
08/01/21 23:12:24
>>246,247
ありがとうございます。
では、早速チャレンジしてみます
249:デフォルトの名無しさん
08/01/21 23:16:08
つーかコンテナにポインタ入れる必要って本当にあるの?
大抵の事ならポインタ入れずに済ませられると思うんだが。
250:デフォルトの名無しさん
08/01/21 23:21:32
ヒープに作成したオブジェクトをコンテナで
管理したい場合もあるんじゃないかな。
251:デフォルトの名無しさん
08/01/21 23:35:47
>>235 だれかおながいします・・
とおもったけどスレチガイ?
252:デフォルトの名無しさん
08/01/21 23:39:15
>>244
>「OSの基本機能であるファイル名の検索機能」とやらのアルゴリズムを
>そっくりそのままDBに応用しようとは考えなかったんだろうか??
Windows Index Search の機能らしいので
アルゴリズム自体はそっくりそのままDBです
本当にありがとうございました
253:デフォルトの名無しさん
08/01/21 23:41:04
>>245-250
class my_class;
vector<my_class*> v1;
普通に使いまくってますが何がいかんの?
254:デフォルトの名無しさん
08/01/21 23:43:59
コピーしたときに問題が起きるのは使い方が悪い。
255:デフォルトの名無しさん
08/01/22 00:19:14
>>235
10
10 12
8
multiset の実装と関係あるかどうか知らんけど。
256:デフォルトの名無しさん
08/01/22 00:35:31
>>255
URLリンク(en.wikipedia.org)
ここみると、そんな凝ったことしてないね。
でも、>>255のようにしないとequal_rangeとかまともに実装できない気もする。
どうなんだろ
257:デフォルトの名無しさん
08/01/22 00:45:39
>>256の記事にも書いてあるけど、親と同じ値なら左部分木に入れる、とか決めておくだけだな
258:デフォルトの名無しさん
08/01/22 00:53:14
右じゃないの。
259:デフォルトの名無しさん
08/01/22 01:00:51
>>258
どちらかに統一しておけばいいんじゃないの?
>>257
左に入れるとして、同じ値を見たら、そのノードの直接の子供としてinsertするのか(255案)、
孫以下の遠い子供として、leafの子としてinsertするのか(この例だと8のrightとして)、どっち?
std::multisetの場合。
260:デフォルトの名無しさん
08/01/22 01:06:36
>>253
newしたオブジェクトを入れるんだったら、
deleteのし忘れ、2重に行ってしまうなどのミスを起こすから
やめとほうがよいというだけのこと。
「気を付ける」なんて言葉は信頼できないので、
やるなら246のいうようにshared_ptrか何か使って、
deleteをコンピュータ任せにするほうがいい。
261:257
08/01/22 01:22:29
>>259
通常と同じ、leafの子としてinsertする
>>255は挿入順の関係でたまたま直接の子になっただけだと思う
262:デフォルトの名無しさん
08/01/22 01:28:48
>>261
それだと、同じ値を持つノードがツリー上で離れてしまいますよね。
equal_rangeをどうやって実装するのか想像がつかないのですが、簡単に教えてもらえませんか?
戻ってきたイテレータを++するたびにO(logN)のサーチが入る???
263:デフォルトの名無しさん
08/01/22 01:36:14
>>262
重複を許そうが許すまいが、二分探索木はそもそもそういうものだろ
隣接した要素が木構造の上では離れた場所に置かれることがある
イテレータをどうやって実装するのが普通かは知らないけど、setとmultisetで事情が変わる訳じゃない
264:デフォルトの名無しさん
08/01/22 01:55:22
>>263
まったくもってそうでした。。。。
イテレータも、単にin-orderでtraverseすれば要素同士が離れていても問題なく連続して触ってくれますね。
265:デフォルトの名無しさん
08/01/24 10:22:33
COAP!
266:デフォルトの名無しさん
08/01/25 08:16:31
COAPってナニ?
267:デフォルトの名無しさん
08/01/25 08:26:55
COAP=Containers of auto_ptr
Effective STLぐらい買え
268:デフォルトの名無しさん
08/01/25 10:01:54
ありがとう
269:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/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
08/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:デフォルトの名無しさん
08/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
08/01/25 16:33:03
なるほど。。なんかfind使う意味なさそうですね。
for ( int i = 0; i < v.size(); i ++ ) {
if ( v[i].name == "もげもげ" ) puts( "一致" );
}
でもいいわけですね。ありがとうございましt。
274:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/01/25 16:48:42
もしstring.find()の検索効率を活用したいなら
文字列の格納先は単一のstringにして
name.append(文字列);
を繰り返してどんどん足していくしかないんじゃ。
で、足すときにnameの何バイト目は何個目の要素か
ってなテーブルを同時に作って、findの結果から調べられる
ようにしておくとか。
276:デフォルトの名無しさん
08/01/25 18:05:03
アルゴリズムの改良でSTLが使えないか質問です。
現在、キー文字列を与えると、それに応じた
文字列を返すSTL::mapのようなコードがあります。
ただ、返す文字列が可変です。例えば、キー"気温" を
与えると”今現在”の気温「5゚C」を文字列で返すと
いった感じです。
現在このコードは ifとelseの連続で構成されたものと
なっておりまして、効率面でも文字列比較を繰り返し
行っており、良いものではありません。
これを実現するのに、できればmapに似た簡単で効率の
いい形で改良できないでしょうか?
277:デフォルトの名無しさん
08/01/25 18:18:02
>>276
すぐに思いつくのは文字列から「文字列を返す関数」へのマップだな
"温度"を与えると「温度を計算する関数」が得られるようにする
278:デフォルトの名無しさん
08/01/25 18:19:08
>>276
map<string, string(*)(void*)> のような、キー文字列→関数のマップを作ればいいんじゃないかな
279:278
08/01/25 18:20:31
void*ってなんだろう・・・無視してくださひ。。
280:デフォルトの名無しさん
08/01/25 19:12:55
>>277-279
早速有難う御座います
なるほど関数ポインタをマップですか。 確かに展望良さそうです。
早速コーディング検討したいと思います。 ありがとうございました!
281:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/01/25 23:21:04
てか>>274に書いてあったorz>>find_if
283:デフォルトの名無しさん
08/01/26 19:04:00
てかstringにsjis入れちゃだめでしょ
284:デフォルトの名無しさん
08/01/26 19:05:50
どこでSJISと特定したのか興味深い。
285:デフォルトの名無しさん
08/01/27 00:03:12
SJISだとしても、別に入れるのは問題ないだろ。
286:デフォルトの名無しさん
08/01/27 00:15:38
findとか使わなきゃね。
287:デフォルトの名無しさん
08/01/27 00:24:35
std::vectorとstd::basic_stringは分かれている必然性があんましない気がする
288:デフォルトの名無しさん
08/01/27 00:27:36
vectorのメモリ連続性が保証されなくなるのは嫌なので統合反対。
289:デフォルトの名無しさん
08/01/27 00:28:10
次期 C++ だと string の連続性が保証されるよ。
290:デフォルトの名無しさん
08/01/27 00:47:37
んじゃ、char_traitsをvectorに入れると只のコンテナじゃ無くなるので統合反対。
291:デフォルトの名無しさん
08/01/27 00:49:36
c_str に触れればいいだけなような
292:デフォルトの名無しさん
08/01/27 00:58:58
>>287
統一してしまうとまずいことがあるよ。
vectorは末尾への要素追加のならし計算時間がO(1)じゃないといけないから、参照カウントによる
copy-on-write最適化ができない。stringにはそういうしばりはないから、COWが可能。まぁ最近
はマルチスレッドの関係でCOWなstringは絶滅危惧種だけど。
他にもあったはずだが、とっさには思いつかない。
293:デフォルトの名無しさん
08/01/27 01:14:54
findしちゃだめって・・もう馬鹿かと。事実上利用不可だろ
294:デフォルトの名無しさん
08/01/27 01:16:36
そうは思わない。入れ物として使うなら十分。
295:デフォルトの名無しさん
08/01/27 01:20:07
c_str 使って外部の検索関数使えばいいだろ。
296:デフォルトの名無しさん
08/01/27 01:20:49
お前ら努力家だな
297:デフォルトの名無しさん
08/01/27 01:25:12
wstringのことも時々でいいから思(ry
298:デフォルトの名無しさん
08/01/27 01:25:43
wstring には SJIS なんて入れられないだろう・・・
299:デフォルトの名無しさん
08/01/27 01:26:03
wstringでSJISが正しく扱えるのかい。
300:デフォルトの名無しさん
08/01/27 01:27:23
これだからWindowsしか知らない奴は。
301:デフォルトの名無しさん
08/01/27 01:31:02
stringは実用なんて論外としても、wstringもサロゲートあぼーんなわけで。。
もう文字列終わってるな
302:デフォルトの名無しさん
08/01/27 01:32:51
そこでUCS-4ですよ。
303:デフォルトの名無しさん
08/01/27 01:36:51
サロゲートあっても find に影響はないだろ?
304:デフォルトの名無しさん
08/01/27 01:37:18
wchar_t はその環境で扱える最大サイズの文字コードを入れる事ができるサイズであって
UTF-16 だと決まってるわけでもないわけだが。実際4バイトの環境もあるし。
まあ、次期 C++ だと char16_t (UTF-16) や char32_t (UTF-32) が追加されるわけだが。
305:デフォルトの名無しさん
08/01/27 01:39:36
しかしwstringだと98系はもうだめだな。
クロスプラットフォームじゃないじゃんstl。。
306:デフォルトの名無しさん
08/01/27 01:40:32
クロス文字エンコーディングじゃないだけ。
307:デフォルトの名無しさん
08/01/27 01:40:52
>>303
UTF-8でもfindは問題ないからそのレベルでいいんだったらwstringを使う意味がない
308:デフォルトの名無しさん
08/01/27 01:41:38
>>304
それはビット幅だけじゃなくて中身もUTF-16/UTF-32であることが保証されてるの?
309:デフォルトの名無しさん
08/01/27 01:42:28
>>303
sizeがだめでしょ。
310:デフォルトの名無しさん
08/01/27 01:43:03
そんなもん中身を入れるコード次第だろ。
311:デフォルトの名無しさん
08/01/27 01:44:59
>>309
sizeは「か」に半濁点とかまで考慮するとUTF-32でもだめ
312:デフォルトの名無しさん
08/01/27 01:45:47
で、おまえらどうやってんの?
string s = "abc"; // sjis!!。findとかしないで。。
wstring s = _T("abc"); // ウニコード。98とかでビルドしないで。サロゲートやばいかも
どっちも地獄だな。CStringの方がましじゃね?
313:デフォルトの名無しさん
08/01/27 01:46:11
>>309
size は配列サイズが取得できれば十分じゃないか?
314:デフォルトの名無しさん
08/01/27 01:49:27
size()/length()はstrlenと等価だから。元々文字数を返すことを期待してはダメ。
315:デフォルトの名無しさん
08/01/27 01:50:00
だからIBMがアレを作ったのさ
なんだっけアレ 眠くて思い出せない
316:デフォルトの名無しさん
08/01/27 01:51:44
ICU
317:デフォルトの名無しさん
08/01/27 01:52:02
集中治療室
318:デフォルトの名無しさん
08/01/27 01:54:11
>>308
Yes.
319:デフォルトの名無しさん
08/01/27 01:55:41
>>311
つか、ウニコード捨てればええだけの話しちゃうの?
ウニコード捨ててもそんなにデメリットないような… … …
320:デフォルトの名無しさん
08/01/27 01:56:41
サロゲートはサブマリン的に最近問題に。。Unicode側は昔っから、
Utf-16はランダムアクセスはできない文字コードですよと言ってきたんだけど
なんとなく流されて2バイトで便利みたいに扱われたり、たいていsizeは文字数を
返すとか説明されたり。。もう混乱の極み。
Javaとかはlengthは2バイト単位の長さを返す仕様に変わり、文字数の取得は
codePointCountが追加されたりどの言語も苦肉の策を講じてる状態。
stlもなんとかしないといけない状況ではある。
321:デフォルトの名無しさん
08/01/27 01:58:34
>>320
日本語だけ扱ってる状況でサロゲートペア関係あるっけ
322:デフォルトの名無しさん
08/01/27 01:58:42
むしろ、stringをタダのコンテナに引きずり落とすくらいの意気込みで。
323:デフォルトの名無しさん
08/01/27 01:59:59
size が文字数返すなら、イテレータは1文字ずつ拾ってくる必要があるし、
そうなった時その型はどうするんだ? って話になる。
UTF-32 で合成があった場合とか、64ビット値を返すのか?
324:デフォルトの名無しさん
08/01/27 02:01:42
やっぱ速度の問題もあるし、javaみたいにsizeとcodePointCountの両方用意
しとくしかないんじゃないかなあと
325:デフォルトの名無しさん
08/01/27 02:02:41
gccのwchat_tは32bitだから楽勝
326:デフォルトの名無しさん
08/01/27 02:04:33
>321
JIS2004と愉快な仲間たち。
>323
final はsizeいくつ、って話だよね。
327:デフォルトの名無しさん
08/01/27 02:05:42
>>325
サロゲートの文字数は取れない点は同じだけどね
328:デフォルトの名無しさん
08/01/27 02:07:28
イテレータだけじゃなくて [ ] も文字数に合わせた形にする必要がある。
でも、ランダムアクセスなんて無理じゃん?
329:デフォルトの名無しさん
08/01/27 02:09:46
world_char_tが定まるまで待ちましょう。
330:デフォルトの名無しさん
08/01/27 02:12:03
結局ランダムアクセス用の冗長なデータを込みにしたクラスにしないとどうしようもないし、
パフォーマンス上そこまで標準に組み込まれることは無いだろう。
まあ、それ用のクラスを string 系列とは別に作ることは可能だろうが、
SJIS とかはまあ無理だな。
331:デフォルトの名無しさん
08/01/27 02:12:42
length(L"final")が5と帰ってきてくれたら、なにか嬉しい?
332:デフォルトの名無しさん
08/01/27 02:14:25
wstringのfind,insert,appendとかはサロゲートも平気そうな気がするけど
なんとも微妙。。
文字とか文字数を意識した扱いをしようとしない限りは平気なのかな・・?
333:デフォルトの名無しさん
08/01/27 02:15:23
文字数を指定しての置換とかはやばそうだな。
334:デフォルトの名無しさん
08/01/27 02:16:12
非常によく使うデータ構造だから、効率を犠牲にして理想に走れないもどかしさ
335:デフォルトの名無しさん
08/01/27 02:16:41
findは大丈夫そうだけど、insert/appendは、サロゲートの前半だけ+別の文字、
みたいな不正な文字列を受け付けるべきか、みたいな話はあるよね。
336:デフォルトの名無しさん
08/01/27 02:17:18
英語圏だとマルチバイトうぜーとかしか思われてないだろうしな。
337:デフォルトの名無しさん
08/01/27 02:18:12
stdc++のレベルで理想に走らなくても良いよ。というか理想がなんなのかも分からないし。この話題はこっち向きじゃないかい。
C++で新しい文字列クラスをつくろう 2
スレリンク(tech板)
338:デフォルトの名無しさん
08/01/27 02:20:06
普通insertする文字とかiteratorもfindの結果のiteratorとかなわけで
問題なくね?
>>333
確かに文字数指定でサロゲート文字の途中とかになってたら文字が切れちゃう
よねぇ
339:デフォルトの名無しさん
08/01/27 02:21:08
もうこういうのは boost の領分かもしれないな。
340:デフォルトの名無しさん
08/01/27 02:21:41
がしがし書き換えたいならutf32に変換してから、書き換えて、utf8なりutf16なりに戻すほうが簡単そうだ。
341:デフォルトの名無しさん
08/01/27 02:24:29
結局、find/appendなどの引数に与える文字が文字の途中などでない、
と文字数指定の関数に文字の途中などの数を指定しない
を守ってればサロゲートもおけ、でいいのかな?
342:デフォルトの名無しさん
08/01/27 02:26:18
まぁあと15年位したら皆UTF-32でのんびりやってるさ
343:デフォルトの名無しさん
08/01/27 02:26:48
>>341
それを守るためにどれだけのコストが掛かるかって話してるんじゃないのか
344:デフォルトの名無しさん
08/01/27 02:27:16
>文字数指定の関数に文字の途中などの数を指定しない
これを守るのがすげー大変そうだ。
345:デフォルトの名無しさん
08/01/27 02:27:59
まだSJISが使われてると思います><
346:デフォルトの名無しさん
08/01/27 02:28:55
SJIS 専用のクラスならまあ作れるだろうな。
347:デフォルトの名無しさん
08/01/27 02:29:01
俺頭から5文字取るみたいなコードとりかえしがつかないくらい書いてるな
348:デフォルトの名無しさん
08/01/27 02:32:47
>>341
文字数ならサロゲートを割ってしまうことはないよ。
サロゲートペア一組で一文字だから。
349:デフォルトの名無しさん
08/01/27 02:33:58
wchar五個分でなくて、5「文字」分きちんと取れるコードを?
350:デフォルトの名無しさん
08/01/27 02:35:13
たとえば、
「か゛」は1文字という扱いでいいのか?
「か゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛(略」
みたいなどうしようもない連中はどうしよう?
351:デフォルトの名無しさん
08/01/27 02:38:26
>>348
std::string(wstring)の「文字数指定」は、1文字が固定長のコード体系が前提だから、サロゲがあると壊れるよ。
>>350
それペアになってなくない?
352:デフォルトの名無しさん
08/01/27 02:38:36
>>348
>サロゲートペア一組で一文字
一組で4バイト(結合文字は6バイトもある)
で、文字数(というより2バイト単位)指定はアウト。
s = サロゲート文字列
s2 = s.substring(0, 5)
とかやったらあぼーんでしょ
353:デフォルトの名無しさん
08/01/27 02:42:20
>>352
文字数というのは、キャラクタ数という意味で使った。
354:デフォルトの名無しさん
08/01/27 02:47:21
CString的にTCHAR使えてさらにクロスなものはないのかね?
355:デフォルトの名無しさん
08/01/27 02:48:52
>>350
合成文字は2キャラクタでしょ。
合成文字をぶった切ると、意味は通じなくなるかもしれないが違法ではない。
356:デフォルトの名無しさん
08/01/27 02:53:07
ああ、その「キャラクタ数」というのは、要するにUTF-32換算なわけか。
357:デフォルトの名無しさん
08/01/27 03:00:31
Winではstringは使うな。2バイト目が1バイト目とかぶってやがるからな。
wstringはサロゲートに注意して使え。途中で切るなよ。
Win98とかまだやってるカスはCStringでも使ってろ。
LinuxではstringでもEUCとUTF-8は2バイト目が1バイト目とかぶらないからまだ
なんとかなるはずだ。
クロスにしたいなら文字列クラスは当然自前だろ?
が俺の現状の認識
358:デフォルトの名無しさん
08/01/27 03:02:31
>>327
ハァ?
359:デフォルトの名無しさん
08/01/27 03:09:34
>>358
へ?
360:デフォルトの名無しさん
08/01/27 03:14:40
>>357
追加でMac OS XはCFString使っとけ。以上。
361:デフォルトの名無しさん
08/01/27 04:50:39
>>357
OS 関係なくてエンコーディングの話だろ?
Windows でも UTF-8 使えば問題ないし、 Linux でも Shift_JIS 使えば問題は出る。
クロスにしたければエンコーディングを OS 任せにしなければ良いだけの話。
たとえば UTF-8 を使うと決めれば std::string でもいけるでしょ。
362:デフォルトの名無しさん
08/01/27 05:05:46
>>361
だけの話・・って、実際にUTF-8でやったことないんだろ?試しにやってみなよ。
APIに渡すとき、コンソルに出すときすべてに変換をかます必要あるだろ?
文字リテラルはどうするんだ?ソース内のUTF-8はまだコンパイラのサポートが微妙だぞ。
現実的じゃないんだよ。OSが正式にサポートしてるSJISとかUTF-16以外を
内部エンコーディングにするのは。
363:デフォルトの名無しさん
08/01/27 05:33:05
1文字が何バイト使うかはどれ使っても一定ではない どれを使うか決まっていればどれ使ってもよい
364:デフォルトの名無しさん
08/01/27 05:48:20
UTF-32は4バイト固定。でも合成文字があるので結局同じ問題は残る。
365:デフォルトの名無しさん
08/01/27 06:53:55
一方ロシアはモールス符号を使った
366:デフォルトの名無しさん
08/01/27 06:59:29
合成文字なんて捨てろ
すべての文字を表現したいなんて無駄の極み
367:デフォルトの名無しさん
08/01/27 08:26:25
おいおい、放棄かよ
368:デフォルトの名無しさん
08/01/27 08:37:31
>>362
入出力と多言語以外の問題はなし 日本語使うんだったらどれでも同じ
入出力にコンバートするのに手間がかかるかどうかだけ
369:デフォルトの名無しさん
08/01/27 10:08:29
全部画像でおk
370:デフォルトの名無しさん
08/01/27 12:33:49
16x16ピクセル(256ビット)のパターンで全ての文字を表現するとかどっかで見たな。
371:デフォルトの名無しさん
08/01/27 13:24:31
文字コード総合スレだと思った
つーかPDFでおk
372:デフォルトの名無しさん
08/01/27 13:25:37
( д ) ゚ ゚
373:デフォルトの名無しさん
08/01/27 15:15:28
>>365
一方ロシアは画像を使った
こっちの方がしっくりくるな。
374:デフォルトの名無しさん
08/01/27 15:52:02
>>370
宇宙の星にそれぞれ新しい文字で名前つけてもあまるだろw
375:デフォルトの名無しさん
08/01/27 16:26:01
一文字32バイトは流石に先取りしすぎだな
376:デフォルトの名無しさん
08/01/27 16:37:26
string path = "c:\\機能仕様書\\01.doc";
path.find("\\");
こんなであぼーんするstringは危険としか言いようがない
377:デフォルトの名無しさん
08/01/27 16:47:52
そんなアホなことをする方が悪い。
378:デフォルトの名無しさん
08/01/27 16:55:52
1文字に1GB
379:デフォルトの名無しさん
08/01/27 16:56:20
もう OCR でいいよ・・・
380:デフォルトの名無しさん
08/01/27 17:24:37
人間様の認識能力を利用する形が最強
381:デフォルトの名無しさん
08/01/27 17:28:05
人間なんてよく読み間違うじゃん
382:デフォルトの名無しさん
08/01/27 17:56:59
>371
CID(AJ15)のことか? あのコードも印刷以外に使うのは
結構アレなんだけどなー。
383:デフォルトの名無しさん
08/01/27 18:00:16
C++
メンバ関数内で
スコープ解決演算子で
classname::メンバ変数 の値変更するのと
this->メンバ変数 の値変更するのは何が違うの?
384:デフォルトの名無しさん
08/01/27 18:04:56
struct P{int m;};
struct C : public P{ int m;
void f(){ this->m = 0; this->P::m = 1; }
};
みたいな話。
385:デフォルトの名無しさん
08/01/27 18:07:20
>>377
findが使えないstringって・・・カスめ
386:デフォルトの名無しさん
08/01/27 18:09:21
path[path.find("\\")] == '\\'になるじゃん、ちゃんと。
387:デフォルトの名無しさん
08/01/27 18:12:41
返答ありがとう。
最初の
this->m は C のオブジェクトのメンバ変数m
this->P::m は何でしょうか?
388:デフォルトの名無しさん
08/01/27 18:14:13
>>386
まじか?
389:デフォルトの名無しさん
08/01/27 18:16:16
>>386
そりゃなるだろwww
390:デフォルトの名無しさん
08/01/27 18:16:42
>>387
P の m にきまっちょるだろう
391:デフォルトの名無しさん
08/01/27 18:22:57
>>386
マジレスすると「能」の2バイト目の「\」がfindで見つかっちゃったんです。
string s = SJISの日本語;
はやっちゃだめなんです。初心者はみんなやってしまうんですが。
392:デフォルトの名無しさん
08/01/27 18:23:56
>>384
>>390
継承したときに変数名かぶった場合コウ書くんですね。
でも、多重に継承した場合、どう書くんだろう?
393:デフォルトの名無しさん
08/01/27 18:29:12
scope
394:デフォルトの名無しさん
08/01/27 18:35:01
>>392
間の型へ一旦 this をアップキャストすると良い。
395:デフォルトの名無しさん
08/01/27 18:35:31
>>391
だから、find とか使わない分には使っていいんだってばよ。
396:デフォルトの名無しさん
08/01/27 18:35:39
あー、ダイヤモンド継承か。
P1::P2::Pb::a = 100;
みたいに、継承順を追いかければ指定できたような・・・
397:デフォルトの名無しさん
08/01/27 18:37:14
char []hoge = SJIS文字列; とかやって、
strchr( hoge, '\\'); ってまずいじゃん。
でも、「char配列にSJIS文字列入れるの禁止」って言うのはどうよ、みたいな。
398:デフォルトの名無しさん
08/01/27 18:37:36
別の言語の癖が出てるぜ
399:デフォルトの名無しさん
08/01/27 18:37:59
>>397
そうそう。そんな感じ。
400:デフォルトの名無しさん
08/01/27 18:42:17
文字コードの話って、荒れる割に全然面白くないし、有用な知見も得られないんだよな。
401:デフォルトの名無しさん
08/01/27 18:44:35
結局毛唐が ASCII 以外どうでもいいと思ってるからな。
402:デフォルトの名無しさん
08/01/27 18:47:46
何も考えずに動いていたCStringがなつかすぃ。。
そういえばなんでがんばってfind禁止のダウングレードのstd::string使ってるん
だったっけ?
だれかどこでも動くCString作ってぇぇ
403:デフォルトの名無しさん
08/01/27 18:49:03
>>393
>>394
>>396
ありがと。
やっぱC++はスゲーや。
Cのシンプルな文法に慣れきったオレには奥が深いぜ。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4812日前に更新/208 KB
担当:undef