アプリ版:「スタンプのみでお礼する」機能のリリースについて

整数を20個入力し、まずそのまま表示してその後大きい順に並べ替えて表示するプログラムを作っているのですが、最大値しか表示されません。多分for文の3重ループの中がおかしいと思うのですがよくわかりません。

#include <stdio.h>

int main(int argc, char* argv[])
{
int c,i,x,max;
int sav = 0;
int before[20];
int after[20];
int check[20] = {0};

printf("整数を20個入力してください: ");

for(i = 0; i < 20; i++) {
scanf("%d",&before[i]);
}

printf("\n");
printf("BEFORE\n");

for(i = 0; i < 20; i++) {
printf("%d\n",before[i]);
}

printf("\n");

max = 0;

for(c = 0; c < 20; c++) {
for(x = 0; x < 20; x++) {
for(i = 0; i < 20; i++) {
if(before[i] > max && check[i] == 0) max = before[i];
sav = i;
}
if(check[sav] == 0) check[sav] = 1;
after[19 - x] = max;
}
}

printf("AFTER\n");

for(x = 0; x < 20; x++) {
printf("%d\n",after[x]);
}

return 0;

}

よろしくお願いします。

A 回答 (6件)

#include <stdio.h>



int main(int argc, char* argv[])
{
int c,i,x,max;
int sav = 0;
int before[5];
int after[5];
int check[5] = {0};

printf("整数を5個入力してください: ");

for(i = 0; i < 5; i++) {
  scanf("%d",&before[i]);
}

printf("\n");
printf("BEFORE\n");

for(i = 0; i < 5; i++) {
printf("%d\n",before[i]);
}

printf("\n");

max = 0;

for(c = 0; c < 5; c++) {
  for(i = 0; i < 5; i++) {
    if(before[i] > max && check[i] == 0)
    {
      max = before[i];
      sav = i;
    }
  }
  if(check[sav] == 0){
    check[sav] = 1;
    after[4 - c] = max;
    before[i] = 0;
    max = 0;
  }
}

printf("AFTER\n");

printf("1番目|2番目|3番目|4番目|5番目|\n");

for(x = 0; x < 5; x++) {
  printf(" %d|",after[x]);
}

return 0;

}



えーと。以上、サンプル?プログラムを添付してみます。
何でここはこうしているの。。。?
等の質問ありましたら返答いたしますが。。。
たぶんそろそろ、「いい加減にさっさと教えろよ。。。_no」という気分になっていると思われるので、これでできるかな?と確認したら自己解決でかまいませんよ(笑

質問がある際は、とことん。返答いたしますのでー。


ちなみに、下の「if文を正したプログラム」をコピーして、該当の部分に貼り付けても、実行させて結果が思い通りにならないと思いますのでご確認ください^^;(たぶん、最大値の数字が1つだけ、後は馬鹿でかい-の数値。だと思いますが。。。
    • good
    • 0
この回答へのお礼

最後まで丁寧にありがとうございましたm(_ _)m
完全に解決しました!

お礼日時:2006/06/12 16:51

どうも~。



>>「トレース」とは何でしょうか?
トレースとは、ソースプログラムを、1行単位、1命令単位で見ていき、どのように内容が変化していくかを確かめる方法。です。
まぁ、デバッグの際に行っていく作業。。。ですかね。。。

学生の、学校で習う授業~などでは、「この値がいくつのとき、ここの数字はいくつになっているか答えなさい」などの問題が出たときは~。。。トレースをして、数字の変化を確かめて答える。。。などということすると思いますが、そんな際に行うのがトレース。。。ですかね。。。


if(before[i] > max && check[i] == 0) max = before[i];
の部分だとすると、「before[0]の場合。。。before[1]の場合。。。brfoer[2]の場合。。。」と、もちろん、それぞれの場合があるので。。。「プログラムの流れにそって、数値がどのように変化しているか」を紙に書きながらプログラムの変数の変化を見ていくのが通常かと思われます。

>>マクロのことについては
define文ですね。
とりあえず、今回のこととは絡まなくても大丈夫な部分なので、それでOKですよ。



なぜ最大値が20回表示されるか。というと。。。
・一度最大値が入るとそれ以降、値の変化がしない。(必要な場合、初期化を行いましょう。
・if文の使い方が間違えている。

。。。ってところですかね?
if文についてですが、正すとこうなります。

for(c = 0; c < 20; c++) {
for(i = 0; i < 20; i++) {
if(before[i] > max && check[i] == 0){
max = before[i];
sav = i;
}
}
if(check[sav] == 0){
check[sav] = 1;
after[19 - c] = max;
}
}


if(before[i] > max && check[i] == 0)max = before[i];

if(check[sav] == 0)check[sav] = 1;
も間違えではないのですが、この場合、そこの1行だけで終わってしまいますので、sav = i;とafter[19 - c] = max;の文に関しては、if文の外の文。だと判断されてしまいます。今回の場合、if文の中にしなければならない処理。だと思われますので、{}の使い方が間違っていると思われます。


長くなってしまったので、サンプルは次の回答にまわします。。。
    • good
    • 0
この回答へのお礼

ご返答ありがとうございますm(_ _)m
if文の{}を忘れていたのか・・・
気づかなかった自分が恥ずかしい・・・

お礼日時:2006/06/12 16:54

どうもこんにちは。



返答遅れて申し訳ないです。

さて。。。状況はどうでしょうか。。。?(汗


>>机上デバッグ
と自分で書きましたが。。。後々考えてみると、トレース。。。ですね。。。(汗
>>3,5,2,3,1
そして、今見返すと、3を2個書いている恥ずかしい自分がいた(笑

>>デバッグしてみましたが相変わらず最大値がずら~っと並ぶだけでした・・・

んー。どのように行ったのでしょうかねぇ。。。(汗
こういうものの確認をする場合、1行ずつ追っていくしかないので。。。
紙に書いて、数字の変化を見ながらやっていくのが一番理解しやすいんですよね(汗


>>ちなみに、20と19はマクロを使って書き換えました。
ここの部分については。。。なんだろう?と思いましたが、流してもいいですかね。。?(ぇ



とりあえず、書きながら要点説明。。。ですかね。。。

問題としては。。。
・1~5の数字で処理を行った場合、最大値は5。ですが、「if(before[i] > max && check[i] == 0) max = before[i];」とりあえずこの文。before配列の添え字を0~4までループさせると、「必ず」5が最大値としてmaxに入る事を確認できますか?(必ず。です。

if(check[sav] == 0) check[sav] = 1;
・ここの文では、checkに0が入っていると、未操作、1が入っていると、操作済み。という形でチェック用に配列を使用しているようですが、上の問題の方で「必ず」5が最大値として取られているので、こちらの文でも「必ず」5の最大値の配列の添え字。しか取れないです。ので、本来は最大値が1回。しか入らないです。最大値で配列が埋め尽くされること自体。がおかしい部分。ですね。


確認して欲しい部分は、「max」の数字の流れ。とc言語での構文。ですかね。。


んー。もうちょっとだけ考えて欲しいので、昼過ぎぐらいになったら勝手に、こうしたら動くかも。。。という文を書き込みたいと思いますね。。。

この回答への補足

すみませんが「トレース」とは何でしょうか?
まだ聞いたことのない言葉なので・・・

マクロのことについては、
int before[20];
int after[20];
int check[20] = {0};

#define N 20
   ・
   ・
   ・
int before[N];
int after[N];
int check[N] = {0};
に変えたということです。
説明不足ですいません。

補足日時:2006/06/12 12:49
    • good
    • 0

どうも~。

2番です。再回答させていただきますね。

こういう、ちゃんと考えてくれる人、結構好きです ̄▽ ̄(知るか。

まぁ、それは置いておきまして。。。と。。。


>>max = before[i];
とりあえず、最大(?)の問題はここなんですよね。
ここで最大値。を代入していると思うのですが、よーく見てみてくださいね。


>>after[19 - x] = max;
で、こことの絡みになりますね。


とりあえずっ。。。

そうですね。。。

1,2,3,4,5
の数を入れて、机上デバッグをしてみてはいかがでしょうか??

ちなみに、オススメ?の並びは
3,5,2,3,1
あたりでしょうかね。




ちょっと急ぎ気味なのでさらに返答は8時以降ぐらいに致しますm(__)m

この回答への補足

デバッグしてみましたが相変わらず最大値がずら~っと並ぶだけでした・・・
ちなみに、20と19はマクロを使って書き換えました。

補足日時:2006/06/10 10:37
    • good
    • 0

>>最大値しか表示されません。



最大値が20個。ですかね?-w-


for(c = 0; c < 20; c++) {
for(x = 0; x < 20; x++) {
for(i = 0; i < 20; i++) {
if(before[i] > max && check[i] == 0) max = before[i];
sav = i;
}
if(check[sav] == 0) check[sav] = 1;
after[19 - x] = max;
}
}


上記記述のループ文についてですが、配列を3つ用意し、入力したもの、チェック用、変換後用。と使用されてると思いますがー。。。

あれですね。

max = before[i];

この記述が、一番最初に内側のループを通った際にしか通過しないことをご確認ください。(xが2になっても3になっても通りません。


理由はー。。。
まぁどうしても分からなければ追記しますけど、お勉強と思って考えてくださいな。


とりあえず、1番さんの書き込みの通り、ソート法をご参照あれ。
一番分かりやすい~やつだと、配列2つ(入力前、変換後)と変数1つで可能ですので。。。

この回答への補足

やっぱりよくわからないのですが、
for(c = 0; c < 20; c++) {
for(x = 0; x < 20; x++) {
for(i = 0; i < 20; i++) {
if(before[i] > max && check[i] == 0) max = before[i];
sav = i;
}
if(check[sav] == 0) check[sav] = 1;
after[19 - x] = max;
}
}
の部分を
for(c = 0; c < 20; c++) {
for(i = 0; i < 20; i++) {
if(before[i] > max && check[i] == 0) max = before[i];
sav = i;
}
if(check[sav] == 0) check[sav] = 1;
after[19 - c] = max;
}
に直しました。

この部分を言葉にすると、
1.cに0を代入
2.iに0を代入
3.before[0]がmaxより大きく、check[0]が0ならばmaxにbefore[0]を代入
4.iをsavに代入
5.iが19になるまで繰り返す
6.もしcheck[sav]が0ならばcheck[sav]に1を代入
7.after[19-c]にmaxを代入
8.cを1増やす
以降繰り返し

であっていますでしょうか?
自分ではあっていると思うのですが・・・

補足日時:2006/06/09 16:37
    • good
    • 0

ソート法の基本を理解してますか?


http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/al …
    • good
    • 0
この回答へのお礼

あらら・・・。
こういうのがあったんですか・・・。まだ習ってなかったので初めて見ました。
とても参考になります。
ありがとうございます。

お礼日時:2006/06/09 16:04

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!