• ベストアンサー

配列の問題

for文を使って2番目に小さい値を出力するようにしたいのですが、どんなプログラムにすればいいでしょうか? 2重ループになりますか? 解る方お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.8

2回ループでやるなら、 まず回答4補足にある方法で一番小さい数を求めます。 その時に一番小さい数が存在する配列番号も一緒に覚えておきます。 で、もう一度最初からループしなおして、 今度は一番小さい数が存在する配列番号を除いた 一番小さい数を求めます。 すると、それは2番目に小さい数になります。 でも、1回ループでもできるし、その方が効率的だと思いますよ。 その場合は、回答4補足にある方法のループの中で 一番小さい数を求めるところを少し工夫します。 まず一番小さい数を覚えておく変数first_minと 二番目に小さい数を覚えておく変数second_minを用意します。 調べるデータがfirst_min以下なら、first_minの値を second_minに移してからfirst_minに今のデータを覚えます。 それ以外でsecond_min以下なら、second_minに今のデータを覚えます。 あと、first_minとsecond_minを初期化するところも少し工夫が いりますね。 もしかすると配列が1個しかない場合にどうするか ということも考える必要があるかもしれません。 これをヒントにコーディングしてみてください。

n1079
質問者

お礼

回答ありがとうございました!

すると、全ての回答が全文表示されます。

その他の回答 (8)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.9

>for文を使って2番目に小さい値を出力するようにしたいのですが、・・  プログラムって、汎用性があると便利です。  「2番目に小さい値」を出したとたん「5番目は?」と、また作り直すのでは・・。 で、質問者様の No.4 さんへの補足ソースをイジッテみました。   (BorlandC++5.6.4)。  ・「1番小さい数」を「任意番目の数」としました(外に for 文追加)。  ・任意番目まで求めるには、直前番目までの順番確定状態をなんらかの形で「保存」しておく必要があります。  ・ここでは、データ配列の先頭から小さい順に「入れ換える」というかたちで「保存」しました。  ・入れ換えは、両手に持った2つのコップの内容物の入れ換えを想定すると判り易いかと・・。      他に、空コップ(ここでは min )ひとつが必要ですよね。  ・全データ個数分入れ換えると、データ配列は、小さい順に並び換わります → 「ソート」。 結果 ・習っていない「ソート」の「ひとつの手法」が習得できました。 ・質問者様のソースが、中核?であったことがわかったはず(下の k を 0 で固定)。 課題 ・「何番目の数」でなく「全体ソート」にするには、・・iTarget 部分は・・? ・下のソースは、内側の for 文で、条件に合った都度、入れ換えているが・・? #include <stdio.h> int GetOrderVal( int iCnt, int iTarget, int data[] ) {  int min = -999, i, k;  for( k = 0; k < iTarget; k++ ){ // 任意番目まで   min = data[ k ];   for( i = ( k + 1 ); i < iCnt; i++ ){    if( min > data[ i ] ){ // 新たな小さい値     min = data[ i ]; // 以降、入れ換え作業     data[ i ] = data[ k ]; // 前のステップで「空」にしたものに代入     data[ k ] = min; //  〃 結果 [ i ] と [ k ] が入れ換わる    }   }  }  return( min ); } void main() {  int data[ 50 ] = { 1, 1 ,3, 3, 5, 6 };  printf( "%d\n", GetOrderVal( 6, 2, data ) ); // 2番目に小さい数  printf( "%d\n", GetOrderVal( 6, 5, data ) ); // 5番目 〃 } 注:インデントに全角空白を用いています。タブに一括変換して下さい。

n1079
質問者

お礼

回答ありがとうございました!

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

つまり, 「最小値を求める」ためには「現在までの暫定的な最小値」を記憶しておけばいいということですね. では, 「2番目に小さい値」を求めるためにはどうすればいいと思いますか? なお, 「現在までの暫定的に 2番目に小さい値」だけ覚えておいてもダメだということは予め指摘しておきましょう. 理論的には「k番目に小さい値」のみがほしいなら線形時間なんだけど, 実際にはソートした方が速かったりするのは事実>#5.

n1079
質問者

お礼

回答ありがとうございました!

n1079
質問者

補足

「現在までの暫定的な最小値」を記憶している時に、「2番目に小さい値」を記憶したところでやめればいいのですか…?

すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.6

#2です。 ちょっと考えてみたのですが、無理にfor1個でやるよりも、for2個のほうが楽そうです。どうもすみません。 ところで、こういうケースはどうなるのでしょうか? 配列の中身が例えば 1,1,3,3,5,6 だった場合、一番小さな数はもちろん1ですが、2番目に小さい数は1なのでしょうか?それとも3なのでしょうか?

n1079
質問者

お礼

回答ありがとうございました!

n1079
質問者

補足

その場合は1になります。 1番小さい数が2つ以上あったら、2番目に小さい数は1番小さい数となります。

すると、全ての回答が全文表示されます。
noname#88772
noname#88772
回答No.5

No.3です。  No.3の回答の方法で処理を実現し、入力値全部についてできるように 拡張してからソートを習うと  “結局、ソートした方が早いじゃん!” と思うようになります。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

「いちばん小さい数の出力方法」でどのようなことをしているのか説明できますか?

n1079
質問者

補足

一番小さい数を出力するには min=data[0]; for(i=1;i<5;i++){ if (min>data[i]){ min=data[i]; } } としました。 最初に一つ指定して、残りの数を一つずつ比較していき、小さい方を新しい最小値にする… といった感じですか?上手く言葉にできなくてすいません。

すると、全ての回答が全文表示されます。
noname#88772
noname#88772
回答No.3

 こんにちは。  今後の事を考えて小さい順に配列に入れる方法がいいかと思います。 そうすると3番目とか4番目に小さい値とかにも対応可能です。  ご参考までに。

n1079
質問者

お礼

回答ありがとうございました!

すると、全ての回答が全文表示されます。
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

う~ん、for文は1つで済むと思いますけどね。 一番小さな数の出力方法がわかるのなら、それにちょっと手を加えるだけですよ。

n1079
質問者

補足

>一番小さな数の出力方法がわかるのなら それはわかります。それに何を加えればいいのかわからないんです…。

すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

ソートしたらどこでも取り出せます バブルソートなら2重ループになります

n1079
質問者

お礼

回答ありがとうございました!

n1079
質問者

補足

初心者なのでまだ「ソート」というのは習っていません。 ただ2回for文を使うだけらしいのですが…

すると、全ての回答が全文表示されます。

関連するQ&A