C言語なら、俺に聞け! <20>

このエントリーをはてなブックマークに追加
>>951
難しくないよ。慣れの問題だよ。
>>949 ちょっと待った。
だとすると、qsortの第一引数はvoid **じゃないとおかしいし、
第三引数は不要になっちゃうよ(sizeof(void *)に決まってるから)。
sortされるのは実体でしょう。

http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libc/stdlib/qsort.c?rev=1.11&content-type=text/plain

これはFreeBSDのlibcのqsort()のソースね。
実際の交換を行っているのはswapcode()というマクロで、
(サイズがlongの場合は特例でswap()の中で交換している)
配列要素をcharまたはlong単位で分割して交換処理をやってるみたい。
他のOSのqsort()も似たようなものではないかと。
954948:02/05/21 22:45
>950
>workのための領域は必要ありません。
普通のソートしか知らないので、入れ替えるときに
work領域を使わない方法というのがちょっとわからないんですが・・・。

qsortってc言語でかかれてるんですか?
もしそうなら、一度ソースを見てみたいです。
955948:02/05/21 22:51
>>953
と思ったらソースをどうも。
しっかり読んで見ます。でも難しそー。
>>955
要するに、ライブラリ関数の中で勝手に交換の為のwork領域を用意して
くれるという事だよ。
957デフォルトの名無しさん:02/05/21 23:35
Win me でVisual C++を使ってます。
これで作ったプログラムをDOS上で動かすことはできるんですか?
>>957
できる
そのVCのヴァージョンが1.5とかなら、
 PureDOSの上で動かせるプログラムが作れるでしょう。
「DOSで動かす」のDOSがWin32Consoleの頭悪い表現なら、
 答えは「できます」
そのほかは
 できません
960デフォルトの名無しさん:02/05/21 23:54
FreeBSD について来る heapsort は malloc してますね。
heapsort のアルゴリズムの都合で
ソートするオブジェクト一個分の作業領域があれば便利なんですな。
ちなみに、最悪の場合を考えると、
heapsort の方が qsort (quicksort) よりがぜん有理。
平均の場合は qsort の方が早いけど
オーダは同じなので、最悪の場合が
気になるようなクリティカルな場合は
heapsort の方がいいかも。
たとえば、4.4BSD 由来の qsort は、同じ値のキーが
多数ある場合、死ぬ程遅いのでこういう時に真っ当な
qsort を持って来るのが面倒なら heapsort を使うって感じ。
「VCを使って作ったプログラム」というところがみそ。
作業領域もheapsortが有利だね。
元のデータ以外は定数個しか要らない。
ガーソ...Linuxにはheapsortなんてついてこないようだ
みんなすごいね。。。
そこまでソートに速さを求めるプログラム組んでんだ。。。

。。それとも単なる追求心?
>>964
ソートでハマッたことのある人は多いと思う。
思ったより遅くて。
>>965
多数のデータから上位10件を表示するのに、ソート使ったら怒られました。
(まあ、確かにえらい遅かったが…)
>>966
ソートしないでどうやるの?
>>967
君は多数のデータから1番大きい数字を探す時もソートを使うんですね
969966:02/05/22 00:15
>>967
えーっと、priority queueを使えと言われたが、
良くワカランかったので上位10個ソート済みの
配列を持ってた(w

データなめ終わったとき配列内に残ってたやつ
が上位10個。
>967
ちょっと考えてみた。

たとえば、n件のデータのトップ10をとるなら
qsortだと最速でO(n*log(n))、最低速だとO(n*n)。
一方、全要素をなめて最大値を探すのはO(n)だから
これを10回繰り返せばトップ10が出るからオーダーはO(n*10)
あと、n>>10だと仮定すればO(n)だな。

結果としてオーダーを見るとソートするより最大値取得を
必要な回数だけ繰り返す方が早い。

ちなみに、priority queueを使えば操作自体はO(n)ですむけど
1件当たりの処理がちょっと重くなるから場合によって使い分ければ良いと思う。
971デフォルトの名無しさん:02/05/22 06:07
大きさ m のヒープを作れば、一回のデータ追加の
操作は O(log(m)) だから、
n 個のデータの上位 m 個を求めるには
O(n log(m)) で済む。
(全部のデータをプライオリティキューにするのでは無くて
これまでに見たことがあるデータの上位 m 個だけをキューに
しておけば良いから。)
972971:02/05/22 06:13
いい忘れたけど、
「大きい順んに m 個」
と言う場合、ヒープは小さい順に並べるのね。
そしたら、ヒープにある m 個のデータのうち
最小の奴だけは O(1) で取り出せ、それを更新する手間が
O(log(m)) になるから...
一番大きなものを探すだけなら、配列内の要素を全て一度だけ見ればOKだろ?
int型の変数に数字以外を入力すると表示させる方法がわかりません
↑「数字以外が入力された」を表示させるでした。
976デフォルトの名無しさん:02/05/22 10:51
>>974-975
何を言っているのかよくわからんが、scanf系関数で数字列以外が入力された場合のことなら、戻り値をチェックすればよい。
O(n log n)とO(n log m)って、まあせいぜい数倍の違いってことか。

でも実際には、データを全部メモリ上に持つ(そして何度も見る)のと
1パスで良い(全部同時に持つ必要はない)のはだいぶ違うね。
978デフォルトの名無しさん:02/05/22 14:01
日時を文字列で持っているのですが、これを1分進めたいという
場合どのようなやりかたがあるでしょうか?
char workdate[15];
strcpy(workdate, "20020522135930");
これが
"20020522140030"
になってほしいのですが。
いったん日時型かなにかに変換するのかなと思ったりしていますが
わからないのでよろしくお願いします。
int year, month, date, hour, min, sec;
sscanf(workdate, "%04d%02d%02d%02d%02d%02d", &year, &month, &date, &hour, &min, &sec);
とりあえずworkdate[16];
NULL文字は入れんでええのかえ
>>974
数値の入力にscanfを直接使うのはC言語では推奨されない。
全てを文字列として読み込み、その後、sscanfで処理すべし。
しまった(*ノД゚)
15でよかよ、ワシのミスじゃ。スマソ
次スレは日下部先生でひとつよろしく
立ててみるぞ。
985(@_@)?:02/05/22 14:27
strncpyはコピーすべき文字数がコピー元の文字列長より少なかったら
自動的に'\0'を入れないようだけど何故'\0'を付けないの?
付けた方が使いやすいと思うんだけど
986伝説の日下部陽一:02/05/22 14:34
次スレ
以降しる!

C言語なら、俺に聞け! <21>
http://pc.2ch.net/test/read.cgi/tech/1022045622/l50
>>985
そういう仕様だからです。
文句はK&Rに言いましょう。
ANSIじゃないの?
今まで我慢してたけど、昨日ともっちで初めてオナニしたよ。
気持ちよかった。いつかともっち
いつかともっち
991デフォルトの名無しさん:02/05/22 14:46
Includeフォルダに
graphics.hがはいってないっす。
どこにああるの?
>>991
いつかともっち
993991:02/05/22 14:48
あいた!すれ残り数ぜんぜん見てなかった。
あっちでききます。
>>991
いつの処理系だ?
TurboC++か?
使っている参考書が古すぎて最近のでは動かんぞ。
そのソースは諦めるべし。
9951000!!:02/05/22 14:48
              ∧            ∧
              / ・           / ';,
             /  ';          /  ';  1000 ワショーイ…
             /   ;______/   ;
          /                  \
         /    /          \     \
        /´   (  ) |____|  (  )      |
       |  /////  (  |     :|    )  /////    |
       |    (   ) :|      |  (   (       |
        |    )  (  |     |   )   )      |
        |   (   ) ';    /   (   (     /
         \  )  (   \/    )   )  ../
           ヽ              ........:::
9961000!:02/05/22 14:49

              ∧            ∧
              / ・           / ';,
             /  ';          /  ';  1000 ワショーイ…
             /   ;______/   ;
          /                  \
         /    /          \     \
        /´   (  ) |____|  (  )      |
       |  /////  (  |     :|    )  /////    |
       |    (   ) :|      |  (   (       |
        |    )  (  |     |   )   )      |
        |   (   ) ';    /   (   (     /
         \  )  (   \/    )   )  ../
           ヽ              ........:::

997991:02/05/22 14:50
TurboC++です。
じゃあ、glibw32.libをDLして使うしかないのかな?
参考書、確かに無茶古いの使ってます。
998デフォルトの名無しさん:02/05/22 14:50

              ∧            ∧
              / ・           / ';,
             /  ';          /  ';  1000 ワショーイ…
             /   ;______/   ;
          /                  \
         /    /          \     \
        /´   (  ) |____|  (  )      |
       |  /////  (  |     :|    )  /////    |
       |    (   ) :|      |  (   (       |
        |    )  (  |     |   )   )      |
        |   (   ) ';    /   (   (     /
         \  )  (   \/    )   )  ../
           ヽ              ........:::

1000かも
最後
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。