• 締切済み

[C言語] 整数を昇順でソートする

このサイト(http://www.kusa.ac.jp/~kajiura/c/hairetsu/newpage3.htm)で、整数を昇順でソートするソースコードが示されています。しかし、for文の中にfor文、その中にif文を用いた箇所が何を実行しているのか全く理解できません。どのような思考を持てばこのようなソースコードに到るのだろう、と困惑しています。自力で書いてみるつもりでしたが、2時間くらい考えて書けませんでした。もっと簡単な方法はないのでしょうか。 #include <stdio.h> #define SIZE 5 main() { int j, k, temp, x[SIZE]; printf("5個の整数を入力してください\n"); printf("昇順に並べ替えて出力します\n"); /* 入力 */ for(j = 0 ; j < SIZE ; j++) { printf("deta = "); scanf("%d", &x[j]); } /* 並べ替え */ for(j = 0 ; j < SIZE - 1; j++) for(k = j + 1; k < SIZE ; k++) if(x[j] > x[k]) { temp = x[j]; x[j] = x[k]; x[k] = temp; } /* 出力 */ for(j = 0; j < SIZE ; j++) printf("%d\n", x[j]); }

みんなの回答

回答No.5

> もっと簡単な方法はないのでしょうか。 これが最も簡単な方法(のひとつ)です。 10枚のカードを昇順に並べることを考えましょう。 まず手札10枚からスタート。 1- 手札の中から最も小さいカードを見つけて場に出す。  これにはfor-loopとif文で実装できます。ココわかりますか? 2- (1)によって手札が1枚少なくなった。手札がなくなるまで(1)を繰り返す  これを行うにはfor-loopひとつで実装できます。 1,2をまとめると 「for文の中にfor文、その中にif文を用い」ればソートできるってことです。 これ以上簡単な手順が思いつきますか?

  • f272
  • ベストアンサー率46% (8013/17127)
回答No.4

#1です。 申し訳ない。#3さんの言うとおり選択ソートです。

回答No.3

厳密にはバブルソートではありませんね。 バブルソートは「隣り合う2要素の順序が逆転していたら交換」を繰り返すもの。 示されたコードは「i番目から配列の末尾までの中から最も小さい要素をi番目と交換」を繰り返しています。これは選択ソートです。

  • maiko0333
  • ベストアンサー率19% (840/4403)
回答No.2

>2時間くらい考えて 2時間?なぜ3時間考えない?なぜ4時間考えない?という先生がいましたね。 自力で解くのが勉強になるのです。 なお、このソートは要素の数が増えると2乗のオーダーで時間がかかります。 要素の数が多いときには使わないようにね。

  • f272
  • ベストアンサー率46% (8013/17127)
回答No.1

いわゆるバブルソートと言われるものです。 https://ja.wikipedia.org/wiki/バブルソート if(x[j] > x[k]) { temp = x[j]; x[j] = x[k]; x[k] = temp; } これはx[j]がx[k]よりも大きかったら,両者を交換しています。 これが for(j = 0 ; j < SIZE - 1; j++) for(k = j + 1; k < SIZE ; k++) この2重ループの中に入っているわけです。 外側のループでjを決めます。 jを固定して考えると,今度は内側のループでそのjよりも大きいインデックスkを決めてx[j]とx[k]を比較するのです。後ろにあるx[k]の方が小さかったら交換するのですから,内側のループが終わったときにはjよりも後ろにあった要素のうちで一番小さい要素が最も前に来ているはずです。 その後外側のループでjを一つづつ増やして行くと,小さい方から順に要素が決まっていきますね。 > もっと簡単な方法はないのでしょうか。 ソートするやり方はいくつもありますが,バブルソートは最も簡単な方法の一つです。

関連するQ&A

  • 配列のソート(昇順)

    最大で30個の整数データを入力し、それを大きい順に並べ替えるプログラムを1次元配列と繰り返し・if文を使って作成しなさい。 という問題で #include<stdio.h> main() { int a[30],x,y,z; printf("Seisu wo 30 ko Nyuryoku \n"); for(x=0;x<=29;x++) scanf("%d",&a[x]); printf("before sort...\n"); for(x=0;x<=29;x++) printf("%d ",a[x]); for(x=0;x<=28;x++) for(y=0;y<=28-x;y++) if(a[y]<a[y+1]) { z=a[y];a[y]=a[y+1];a[y+1]=z; } printf("\n after sort...\n"); for(x=0;x<=29;x++) printf("%d ",a[x]); } ここまで出来たのですが最大で30個ということなので(例)「10個の整数を入力して Z を入力したら終了」 としたいのですがどこをどのようにすればいいですか?

  • C言語のソートプログラム

    学校でプログラミングの課題が出たので自分のパソコンに Microsoft Visual C++ 2010 Express をインストールして作ってみました。 それが以下のプログラムです。 これは任意の値nを入力してa[n]までの配列をつくり それを降順に並び替えるものです。 #include <stdio.h> #define N 10000 int main(){ int a[N],i,j,max,min,n,temp; n=0; printf("n="); scanf("%d",&n); if(N<n){ return 0; } else if(n<=0){ return 0; } else if(n<=N){ for(i=0;i<n;i++){ printf("a[%d]",i); scanf("%d",&a[i]); } max=min=a[0]; for(i=1;i<n;i++){ if(max<a[i]){ max=a[i]; } else if(min>a[i]){ min=a[i]; } } printf("a[i]のソート結果\n"); for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]){ temp=a[i]; a[i]=a[j]; a[j]=temp; } } } for(i=0;i<n;i++){ printf("a[%2d]=%d\n",i,a[i]); } printf("Max=%d\n",max); printf("Min=%d\n",min); } } これを実行すると 最初に入力した配列の順番のまま表示されてしまいます。 例えば n=4 a[0]7 a[1]4 a[2]6 a[3]1 a[i]のソート結果 a[0]7 a[1]4 a[2]6 a[3]1 のようにです。 しかしプログラミング上では for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]       temp=a[i];       a[i]=a[j];            a[j]=temp;        }        }        } のようにiとjを比較して a[0]がa[1]より大きければa[0]とa[1]を交換する。 あとはa[0]とa[2], a[0]とa[3]...a[3]とa[4]まで for文の続く限り繰り返すように書いたはずです。 まだ勉強し始めた私にはどこが間違っているのか分からないので 分かる方はご指摘をお願いします。

  • C言語について。

    今、C言語に関する問題をやっているんですが、いまいちわかりません。 その問題というのは↓ ≪問題5 (繰り返し) 例題をもとに、次のような九九の表を出力するプログラムを作成しなさい。  1 2 3 4  5  6  7  8  9  2 4 6 8 10 12 14 16 18  ~(略)                                               ≫ という問題です。それで、その例題というのは↓ ≪例題4 (for文、do while文)  次のプログラムは、入力された整数を一辺とする正方形を出力するプログラムである。動作確認をしなさい。  4       (←入力)  ****  (←出力)  ****  ****  **** /* 正方形 */ #include <stdio.h> void main() {     int hen, i, j;     do{        printf("数字(2~9)を入力してください : ");        scanf("%d", &hen);        if( hen < 2 || hen > 9 )           printf("入力エラーです!\n");     }while( hen < 2 || hen > 9);     for( i = 1 ; i <= hen ; i++)     {         for( j = 1 ; j <= hen ; j++)           printf("*");         putchar('\n');    } }  ≫ ≪例題5 (for文、do while文) 次のプログラムは、入力された整数を一辺とする二等辺三角形を出力するプログラムである。動作確認しなさい。  4      (←入力)  *     (←出力)  **  ***  **** /* 二等辺三角形 */ #include <stdio.h> void main() {     int hen, i, j;     do{        printf("数字(2~9)を入力してください : ");        scanf("%d", &hen);        if( hen < 2 || hen > 9 )           printf("入力エラーです!\n");     }while( hen < 2 || hen > 9 );     for( i = 1 ; i <= hen ; i++ )     {            for( j = 1 ; j <= i ; j++ )              printf("*");          putchar('\n');     } }  ≫ 以上の二つが例題です。 わかりづらかったらすみませんm(_ _)m わかる方(問題5を)教えてくださるとありがたいです。

  • C言語でのソートについて質問

    shianData配列の一列目が性別、二列目が年齢、三列目が部署です。 これを部署、年齢の優先順位で並べ替えたい。部署は昇順、年齢は降順です。 しかし以下のプログラムですとそれぞれの列が独立に並び替えられてしまいます。 このプログラムを直していただけないでしょうか。できれば解説もお願いします。 #include<stdio.h> void main(void){ int i,j,Temp; int shainData[][3]={{0,20,1},{1,34,1},{0,55,1},{1,43,3},{1,21,3},{0,43,3},{0,21,2},{1,67,3},{0,83,3},{0,24,2},{1,56,3},{0,78,3},{0,44,1},{1,33,1},{0,22,2},{1,66,3},{0,55,1},{1,31,1},{0,41,3},{0,43,3}};     for(j=19;j>0;j--){ for(i=0;i<j;i++){ if(shainData[i][2]<shainData[i+1][2]){ Temp=shainData[i][2]; shainData[i][2]=shainData[i+1][2]; shainData[i+1][2]=Temp; } } } for(j=19;j>0;j--){ for(i=0;i<j;i++){ if(shainData[i][1]<shainData[i+1][1]){ Temp=shainData[i][1]; shainData[i][1]=shainData[i+1][1]; shainData[i+1][1]=Temp; } } } for(i=0;i<20;i++){ printf("%d %d\n", shainData[i][1],shainData[i][2]); } }

  • C言語プログラムについての質問です。下のプログラムがなぜ降順で出力され

    C言語プログラムについての質問です。下のプログラムがなぜ降順で出力されるのか分かりません。何回も確認したのですが、不等号の向きが昇順になっているのに、どうして降順になるのかが理解できません。 ご教授お願いします。   #include <stdio.h>   #define MAX 10000   int main (int argc, const char * argv[]) { int N,data[MAX],d[MAX],j,k,w,x,a; x=0; a=1; do{printf("学生番号を入力してください\n");    scanf("%d",&N);   if(N!=0){printf("得点を入力してください\n"); scanf("%d",&data[N]);}x++;} while(N!=0);   for(j=0; j<x;j++){ d[j]=data[j];} for(j=0; j<x;j++)      {for(k=0;k<x-j-1;k++){   if(d[k]>d[k+1]){ w=d[k]; d[k]=d[k+1]; d[k+1]=w;}}} printf("昇順での整列結果\n"); for(j=x-1;j>0;j--){ printf("%d位 %d点\n",a,d[j]);a++;} return 0; }

  • C言語の問題

    以下はC言語の問題です。お教えください。 1000以下の素数を求めるプログラム prog.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 です。 僕の考えでは、 #include <stdio.h> #include <math.h> main(){ int i; int j; int ix; int k; printf("正の整数を入力して下さい: "); scanf("%d",&i); ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++) { if(i%j==0) { k=1; } } if(k==0) { printf("%d は素数です\n",i); } else { printf("%d は素数ではありません\n",i); } となると思うのですが。どうやら違うようです。全然わからないので、正しい答えを教えてください。

  • C言語についてなのですが、

    C言語についてなのですが、 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<search.h> int main(void) { int i,j,k,temp,n,count,time,list[65537]; clock_t startTime, endTime; printf("取得する乱数の個数を入力してください\n"); scanf("%d",&n); srand((unsigned)time(NULL)); printf("Before sort\n"); startTime = clock(); for(i = 0; i < n; i++) { list[i] = rand(); /* printf("%d\n", list[i]);*/ } count = 0; for (i = 1; i < n; i++) { for (j = i; j < n-i-1; j++) { count++; if(list[j] < list[j+1]) { temp = list[j]; list[j] = list[j+1]; list[j+1] = temp; } } } endTime = clock(); printf("\nAfter sort\n"); for(k = 0; k < n; k++) { /* printf("%d\n", list[k]);*/ } printf("\n比較回数:%d\n", count); printf("実行時間:%.4f秒\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); return 0; } 上記のソースコードをcygwinで gcc -Wall -o k5-1-2 k5-1-2.c でコンパイルしようとすると k5-1-2.c:関数'main'内 k5-1-2.c:14:error:called object is not a function と表示されます。 いろいろなサイトを参考にして乱数取得用に srand((unsigned)time(NULL));を使うように書かれていたので使っているのですが、何かだめなのでしょうか?自分ではお手上げ状態で。

  • C言語

    昇順にソートしたいのですけど、このソースだと実行しても、最後に入力した文字が、表示されます。分からないので宜しくお願いします。(例21,34 55を入力すると、55,55,55と表示されます) #include <stdio.h> void sort1(int *dt, int n) { int i,temp,exchg=0; while (exchg<n) { for (i=1; i<n; i++) { if (dt[i-1] > dt[i]) { temp=dt[i-1]; dt[i-1]=dt[i]; dt[i]=temp; } } exchg++; } }int main(void) { int data[10]; int no=3; int i,*p_data; p_data =data; printf("%d個の整数を入力してください。\n",no); for (i=0; i<no; i++) { printf("data[%d]:",i); scanf("%d", p_data); } sort1(data,no); puts("これからの値を昇順に並び替えました。"); for (i=0; i <no; i++) printf("data[%d]=%d\n", i,*p_data); return(0); }

  • C言語プログラミングの問題がわかりません・・・。

    ただいまC言語を勉強している者です。 【入力するデータ数と各データ(整数)を入力していき,0 以下の整数の数,正の整数の数,0 以下の整数の合計,正の整数の合計を求めるプログラムを作成せよ。】 という問題があり、とりあえず #include "stdio.h" void main() { int i,j,k,l=0,m=0,goukeisei=0,goukeifu=0; printf("入力するデータ数:"); scanf("%d",&i); for(j=1;j<=i;j++); { printf("データを入力してください(整数):"); scanf("%d",&k); if(k>0){ l++; goukeisei+=k; }else{ m++; goukeifu+=k; } } printf("正の整数の数%d\n",l); printf("0以下の整数の数%d\n",m); printf("正の整数の合計%d\n",goukeisei); printf("0以下の整数の合計%d\n",goukeifu); } と作ってみたのですが、入力するデータ数の繰り返しがされません(1回入力して終わりになってしまいます);; for文の使い方が間違っているのでしょうか・・・ 詳しい方教えてくださいm( _ _ )m 尚環境はXPでVC++2008を使っています。よろしくお願いします。

  • C言語 素数判定

    1000以下の素数を求めるプログラム kadai7-2.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 という問題なのですが、以下のプログラムを実行しても動きませんでした。どこが違うのでしょうか。ご指摘お願いします。 #include<stdio.h> #include<math.h> main(){ int i,j,ix,k,h; for (i=2;i<=1000;i++){ ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++){ if(i%j==0){ k=1; } } if(k==0){ printf("%4d",i); h+=1 if(h=15){ printf("\n"); h=0; } }

専門家に質問してみよう