• ベストアンサー

並べ替えのプログラム

整数を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; } よろしくお願いします。

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

  • ベストアンサー
  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.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つだけ、後は馬鹿でかい-の数値。だと思いますが。。。

cermet
質問者

お礼

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

その他の回答 (5)

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.5

どうも~。 >>「トレース」とは何でしょうか? トレースとは、ソースプログラムを、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文の中にしなければならない処理。だと思われますので、{}の使い方が間違っていると思われます。 長くなってしまったので、サンプルは次の回答にまわします。。。

cermet
質問者

お礼

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

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.4

どうもこんにちは。 返答遅れて申し訳ないです。 さて。。。状況はどうでしょうか。。。?(汗 >>机上デバッグ と自分で書きましたが。。。後々考えてみると、トレース。。。ですね。。。(汗 >>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言語での構文。ですかね。。 んー。もうちょっとだけ考えて欲しいので、昼過ぎぐらいになったら勝手に、こうしたら動くかも。。。という文を書き込みたいと思いますね。。。

cermet
質問者

補足

すみませんが「トレース」とは何でしょうか? まだ聞いたことのない言葉なので・・・ マクロのことについては、 int before[20]; int after[20]; int check[20] = {0}; を #define N 20    ・    ・    ・ int before[N]; int after[N]; int check[N] = {0}; に変えたということです。 説明不足ですいません。

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.3

どうも~。2番です。再回答させていただきますね。 こういう、ちゃんと考えてくれる人、結構好きです ̄▽ ̄(知るか。 まぁ、それは置いておきまして。。。と。。。 >>max = before[i]; とりあえず、最大(?)の問題はここなんですよね。 ここで最大値。を代入していると思うのですが、よーく見てみてくださいね。 >>after[19 - x] = max; で、こことの絡みになりますね。 とりあえずっ。。。 そうですね。。。 1,2,3,4,5 の数を入れて、机上デバッグをしてみてはいかがでしょうか?? ちなみに、オススメ?の並びは 3,5,2,3,1 あたりでしょうかね。 ちょっと急ぎ気味なのでさらに返答は8時以降ぐらいに致しますm(__)m

cermet
質問者

補足

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

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.2

>>最大値しか表示されません。 最大値が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つで可能ですので。。。

cermet
質問者

補足

やっぱりよくわからないのですが、 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増やす 以降繰り返し であっていますでしょうか? 自分ではあっていると思うのですが・・・

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.1
cermet
質問者

お礼

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

関連するQ&A

  • printf、最大値の出し方

    3つの整数を入力し、どれが最大値かを判別するプログラムを作りたいです。 #include<stdio.h> main() { int i, x, max; max = 0; i = 1; while(i <= 3) { printf("整数:"); scanf("%d",&x); if (x > max) { max = x; } i++; } printf("最も大きい整数は%d\n", max); } とすると 整数:と3回表示されますが、これを一つ目の整数:、二つ目の整数:3つ目の整数:と表示されるようなプログラムにするにはどうしたらよいでしょうか。

  • プログラムが上手く動作しません。

    質問です。 1.整数を1個入力し、その数を3で割った余りが0ならば"Good morning"、1ならば"Good evening"、2ならば"Good afternoon"と出力するプログラムを作成せよ。ただしswhitc文を用いること。 という問題で私は #include <stdio.h> main() {      int a;      printf("整数a:");      scanf("%d",&a);      switch(a%3)      {      case '0':           printf("Good morning \n");           break;      case '1':           printf("Good evening \n");           break;      case '2':           printf("Good afternoon \n");           break;      } } と考えましたが実行しても入力はできますがprintfが表示されません。 どこが間違っているのでしょうか?ちゃんとコンパイルはできるのですが・・・。 2.10個の整数値をキー入力し、合計と平均値を計算してその結果を表示するプログラムを書きなさい。 #include <stdio.h> main() {      int a[11],b,c,i;      for(i=1;i<11;i++)      {           printf("整数%d:\n",i);           scanf("%d",&a[i]);      }      for(i=1;i<11;i++)           b+=a[i];      c=b/10;      printf("合計値は%d",b);      printf("平均値は%d",c); } というプログラムを考えましたが、計算結果がめちゃくちゃになってしまいます。 これもどこを直したらいいべきでしょうか?

  • ポインターを使った並べ替え

    ポインタを用いてソートを行うプログラムを作成しています しかし、関数部分が悪いのか、上手く作動されません よろしければ、アドバイスをいただけると嬉しいです #include <stdio.h> #define MAX 10 #define RandMax 1000 void select_sort(int *a, int n){ int *i, *min, *last, t; last=a+n; for(i=a; i<last; i++){ min=a; for(i=a+1; i<last; i++) if(*i<*min) min=i; t=*min; *min=*i; *i=t; } } main(){ int *a, i; a=(int*)calloc(MAX,sizeof(int)); for(i=0; i<MAX; i++) a[i]=rand()%RandMax; select_sort(a, MAX); printf("data size=%d \n", MAX); for(i=0; i<MAX; i++){ printf("%5d", a[i]); if(i%10==9) printf("\n"); } } 以上が私の作成したプログラムです よろしくお願いします

  • 並べ替え

    次のようなプログラムを作れ。 1.数値を次々に読み込んで配列に1番目から順に格納する。 2.配列に格納されている数値を逆の順番に並べ換える (最後に読み込んだ数値が配列の1番目に入る)。 3.その配列の内容を1番目から順番に画面に出力する。読み込み、逆転、出力の部分はそれぞれ関数にすること。 という課題をやっています。下のように作ってみたんですが 上手くいかなくて・・・ 何処が悪いか教えて下さい。 #include <stdio.h> #define MAX 100 void reve(int *, int *); void read(int *, int *); void write(int *,int *); int main () { int x[MAX]; int n=0; read(&n, x); reve(&n, x); write(&n, x); return; } void read(int *n, int x[]) { while(scanf("%d", &x[n]) == 1 ) { n += 1; } return; } void reve(int *n, int x[]) { int i, j, y; for(i = 0, j = n-1; i <j; i++, j--) { y = x[j]; x[j] = x[i]; x[i] = y; } return; } void write(int *n, int x) { int i; for(i = n; i = 0; i--) { printf("x[%d] = %d\n", i, x[i]); } return; }

  • ポインタのプログラムについて

    以下のプログラムを実行したとき、表示される値を余白に記述せよ。ただし、配列idataは1000番地から格納されているとする。また、表示結果*8**~*10**の箇所で、正しく計算された値のみ表示させるには、maxはいくらに設定すればよいか。という課題なんですが、実際にプログラムを作ってみてmaxの箇所を4にしてみたところ間違いと言われたので正しいmaxの値を教えて下さい。 #include<stdio.h> int main(void) { int iv,idata[]={2,4,6,8,10,12},*ip,i,max; iv=idata[0]; printf("*1*ivの値=%d\n",iv); ip=&idata[0]; printf("*2*ipの値=%p\n",ip); ip=&idata[1]; printf("*3*ipの値=%p\n",ip); ip=&idata[2]; printf("*4*ipの値=%p\n",ip); iv=*ip; printf("*5*ivの値=%d\n",iv); iv=*ip+3; printf("*6*ivの値=%d\n",iv); iv=*(ip+3); printf("*7*ivの値=%d\n",iv); max=4; *ip=0; for(i=0;i<max;i++){ printf("*8**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+1)=10; for(i=0;i<max;i++){ printf("*9**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+3)=20; for(i=0;i<max;i++){ printf("*10**(ip+%d)=%d\n",i,*(ip+i)); } ip=&idata[0]; printf("*11*ipの値=%p\n",ip); ip=ip+2; printf("*12*ipの値=%p\n",ip); iv=*ip+3; printf("*13*ipの値=%d\n",iv); iv=*(ip+3); printf("*14*ivの値=%d\n",iv); ++ip; printf("*15*ipの値=%p\n",ip); } ヒントは”正しく計算された値のみ”という部分らしいのですが、自分にはまったく分りませんでした。

  • プログラム作成が出来ません

    プログラム作成の課題でエラーが出て進めません (1)~(3)までだけなら作成できるのですがどうしても(4) を表示させることができません^^; (1)3~99までの奇数を7*7の2次元配列に読み込み表示 (2)(1)の配列の行と列を入れ替えたものを表示 (3)全要素の平均 (4)要素の中から9の倍数を選び出し表示 添削よろしくお願いします。 #include <stdio.h> main() { int a[7][7]; int i,j,ave,sum; int c; for(i=0; i<7; ++i) { for(j=0; j<7; ++j) { a[i][j] =3+(j*2)+(i*14); } } for(i=0; i<7; ++i) { for(j=0; j<7; ++j) { for(c=0; c<49; ++c) { if((3+(j*2)+(i*14))%9==0) { c=3+(j*2)+(i*14); } } } } sum=0; for(i=0; i<7; ++i) { for(j=0; j<7; ++j) { sum=sum+a[i][j]; } } ave=sum/7/7; for(i=0; i<7; ++i) { for(j=0; j<7; ++j) { printf( "%2d ", a[i][j] ); } printf( "\n" ); } printf("\n"); for(i=0; i<7; ++i) { for(j=0; j<7; ++j) { printf( "%2d ", a[j][i] ); } printf( "\n" ); } printf("\n"); printf("average=%d\n",ave); printf("\n"); for(c=0; c<49; ++c) { printf("%d",c); } } 長々と失礼しました・・・

  • プログラムの添削

    以下のような数当てゲームを作りました.なるべくうまいプログラムを書けるようになりたいのですが,どのような改善点がありますか?よろしくお願いします. /*数当てゲームを作りなさい.*/ #include<stdio.h> void maegaki(void); /*このように関数を定義しまくることに意味はあるのか?main関数はすっきりするけど.*/ void in_check_out(int i); int main(void) { int i; int j; maegaki(); for(j=0;j<10;j++) { scanf("%d",&i); in_check_out(i); if(!(i-1)) return 0; printf("残り%d回です.\n",9-j); } return 0; } void maegaki(void) { printf("数当てゲームをはじめます.\nぼくの好きな整数を当ててください.\nチャンスは10回です.\nヒントはボゾン\n"); } void in_check_out(int i) { if(!(i-1)) { printf("正解!答えは1です.\n"); } else { printf("残念!\n"); if(i>1) printf("%dより小さいです.\n",i); else printf("%dより大きいです.\n",i); } }

  • Cの素人がやってしまう・・・と言われた使い方

    関数set()を作って、下にコメントアウトされているプログラム と全く同じ動作をするプログラムを完成させよ。 main内部を変更してはならない。 関数set()内では鈎括弧を使用してはならない。 という問題で、終わるときにチェックされたのですが どうもsetでの中身が素人がよくやるやつ、といわれました。 int x[MAX]とやれ?ということなのでしょうか それともやはり&(*(x+i))の部分がおかしいということでしょうか? 確かにアドレスにアドレスを聞いているような理解としか、今は言いようがないのですが そいえば前回&*を使ってる人がいるけど・・・という話を聞きました 何かご指摘あればうれしいです 以下がコードになります。 #include <stdio.h> #define MAX 10 void set(int *x); int main() { int x[MAX]; int j; set(x); printf("KEKKA\n"); for (j = 0; j < MAX; ++j) { printf("%d\n", x[j]); } return 0; } void set(int *x) { int i; for(i = 0; i < MAX; ++i){ scanf("%d",&(*(x+i))); } } /* int main() { int x[MAX]; int j; for (j = 0; j < MAX; ++j) { scanf("%d", &x[j]); } printf("KEKKA\n"); for (j = 0; j < MAX; ++j) { printf("%d\n", x[j]); } return 0; } */

  • プログラミングで二番目に大きい数を表示する

    指定された個数(100個以下)だけ整数を読み込んで,読み込んだ整数の一覧,それらのうちの最大値と二番目に大きい値とを表示するプログラムを作成。最大となる値が複数入力された場合も正しく処理する。 このプログラムで入力した数字が全部同じ時、二番目に大きい値はありません。と表示したいのですが、どのようにしたらいいのかわかりません。教えてください。あとこのプログラムで最大値と二番目に大きい値出せたのですが、念のため問題ないか確認お願いします。 #include <stdio.h> #define NUMBER 100 /*整数の個数の上限*/ int main(void) { int i; int num; int kazu[NUMBER]; int max; int sec; printf("整数は何個ですか:"); scanf("%d", &num); puts("整数を入力してください。"); for(i = 0; i<num; i++){ printf("%3d個目:",i+1); scanf("%d", &kazu[i]); } printf("入力された整数は%d個で、\n",num); for(i=0;i<num;i++) printf("%d ",kazu[i]); printf("です。\n"); sec = max = kazu[0]; for(i=1; i<num; i++){ if(kazu[i]>max) max=kazu[i]; } for(i=0;i<num;i++){ if(kazu[i]>max){ sec=max; max=kazu[i]; }else if((max>kazu[i]) && (kazu[i]>sec)) sec=kazu[i]; } printf("最大値は%dです。 \n",max); printf("二番目に大きい値は%dです。\n", sec); return(0); }

  • 最大値を求める

    3つの整数を入力して、最大値を求めるプログラムを作りたいのですが、整数を入力するところまでは うまくいくのですが、結果が、255、と出てしまいます。どこがおかしいのかが解かりません。 どなたか教えていただけませんか? 宜しくお願いします。 #include <stdio.h> int main(void) { int num[3]; int max, i, j; puts("三つの整数を入力してください"); for(i = 0; i < 3; ++i) { printf("整数%d:", (i + 1)); scanf("%d", &num[i]); } max = num[0]; for(j = 0; j < 3; ++j) { if(max < num[j]) { max = num[j]; } } printf("最大値は%dです。\n", max); return 0; }

専門家に質問してみよう