数値の並び替えをするには?


トト  2004-11-22 00:46:44  No: 55243

数値を入れた配列を大きい方から並びかえたいのですがうまくいきません。どこか間違っているところがありますでしょうか?プログラムを載せるのでどなたか意見をください。

for(j=1; j<254; j++){
  for(i=1; i<349; i++){
    x = i;  
    y = j;
    max = value[x][y];

  for(k=i+1; k<349; k++){  
    if(value[k][j] > max){
        x = k; y = j;  
        max = value[x][y];
  }}
  for(m=j+1;m<254;m++){
    for(l=1; l<349; l++){
      if(value[l][m] > max){
        x = l; y = m; 
        max = value[x][y];
  }}}
         work = value[i][j];
         value[i][j] = value[x][y];
         value[x][y] = work;
}}  

このようなプログラムです。二行の配列の並び替えをしたいのですが,これだとボタンを押したとたんにプログラムが止まってしまいます。どなたかアドバイスをください。お願いします。


てつや  2004-11-22 02:48:59  No: 55244

valueの大きさが良くわかりませんが、少なくともvalue[0][0]の値は
無視されていますが良いのですか?
オーバーフローしていませんか?


トト  2004-11-22 03:45:52  No: 55245

返信ありがとうございます。value[][]はやはりvalue[0][0]からなければならないのでしょうか?value[][]の値は

for(j=1; j<254;j++){
 for(i=1;i<349;i++){
   value[i][j] = Getpixel(i,j);}}

のようにピクチャボックスから値を取るようにしてあります。やはりしっかりと
i=0 , j=0  から行わなければならないのでしょうか?よろしくお願いいたします。


トト  2004-11-22 04:12:45  No: 55246

追加して記述させていただきます。

for(j=1; j<254;j++){
 for(i=1;i<349;i++){
   value[i][j] = Getpixel(i,j);}}

for(j=0; j<254;j++){
 for(i=0;i<349;i++){
   value[i][j] = Getpixel(i,j);}}
とし、また並びかえる範囲も
i=0,j=0からとしましたが、とまってしまう現象は直りません。並び替え前の値で平均をとり、表示させるようにしましたが、こちらはしっかりと表示されるので、並び替えるコードがおかしいと思われます。どこが間違っているのでしょうか?お願いいたします。


てつや  2004-11-22 08:49:16  No: 55247

>for(j=0; j<254;j++){
> for(i=0;i<349;i++){
>   value[i][j] = Getpixel(i,j);}}

COLORREF value[349][254] ;
が宣言されていれば、このソースで止まってしまう理由は見つかりません。

そもそも、"とまってしまう"とはどのような現象をさしていますか。
1. プログラムが強制終了してしまう。
2. プログラムが応答不能になってしまう。

1.であれば、デバッグ実行して、強制終了時の場所を特定し、その時の変数が
おかしくないか確認しましょう。 (iが 350になってないかとか )

2.の場合、無限ループに陥ってしまっている可能性があります。
意外と
 for( j = 0 ; j < 254 ; i ++ )
     ジェイ   ジェイ    アイ
とか同等の凡ミスかもしれません。


fuku  2004-11-22 11:27:52  No: 55248

止まっているのではなく、処理が終わっていないのだと思います。

このソースには4重のforループが存在しますが、この4重のforループを抜けるには、
約40億回ループしないといけないように見えるのですが・・・
#実際に実行してみたところ、抜けるのに約40秒かかりました

qsortでソートしてみてはいかがですか?


トト  2004-11-22 22:05:57  No: 55249

返信ありがとうございます。とまってしまう現象は、

2. プログラムが応答不能になってしまう。

です。処理が終わらないのかわかりませんが、Ctrl+Alt+Deleteを押すと応答なしとでてきます。結局、強制終了するしかなくなってしまうのです。ほかにいい方法があるのでしょうか?プログラム的には間違ってないと思うのですが…。凡ミスもなさそうですのでどうしたらよいのかわかりません。qsortという関数を用いればならびかえられるのでしょうか?やってみます。


YuO  2004-11-22 22:46:17  No: 55250

> です。処理が終わらないのかわかりませんが、Ctrl+Alt+Deleteを押すと応答なしとでてきます。

処理をしているのかどうかを確かめましたか?
#例えば,途中にprintf文を挟む等。

> プログラム的には間違ってないと思うのですが…。凡ミスもなさそうですのでどうしたらよいのかわかりません。

間違っているかどうかは,とりあえず数を少なくしてみれば「ソート自体」の成否はわかると思います。
とりあえず,提示されているプログラムはO((NM)^2)の複雑さですから,
NかMの片方が2倍になると,時間は凡そ4倍かかります。
#N : valueの配列要素数, M : value[0]の配列要素数

> qsortという関数を用いればならびかえられるのでしょうか?やってみます。

Cにおける基本的なソート関数です。
ちなみに,C++であればstd::sortを使ったほうが簡単です。


トト  2004-11-23 03:29:22  No: 55251

返信ありがとうございます。for文の中の数値を(並び替えの部分)少なくして実行したところ、問題なく処理できてました。i<20,j<20とか少ないとできるのですが、やはりi<350,j<250とか大きくすると応答なしになってしまいます。
std::sort  とはどんなものなのでしょうか?どういった使い方をすればよいのでしょうか?よろしくお願いします。


YuO  2004-11-23 06:34:05  No: 55252

> i<20,j<20とか少ないとできるのですが、やはりi<350,j<250とか大きくすると応答なしになってしまいます。

前に書いたとおり,おおよそ二乗に比例する時間がかかります。
つまり,(20, 20)が(350, 250)になると,それぞれ17.5倍と12.5倍ですから,
単純計算で48000倍の時間がかかります。

応答無しは,単にそれが原因でしょう。

これに対して,例えばクイックソートを使うと最善の場合はO(Nlog N)ですから,
だいたい1700倍の時間で済むことになります。
#実際には定数項の関係でそうはならないが。

> std::sort  とはどんなものなのでしょうか?どういった使い方をすればよいのでしょうか?よろしくお願いします。

<algorithm>にあるソートを行う関数テンプレートです。
指定した範囲のオブジェクトを,指定した関数・関数オブジェクト又は<演算子を用いて順序づけ,
それに従って並び替えます。

επιστημηさん(http://www005.upp.so-net.ne.jp/episteme/)が
著書「Standard Template Library プログラミング」を絶版を期に公開されています。
http://www005.upp.so-net.ne.jp/episteme/html/stlprog/
これを読んでみるのがよいかと。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加