配列の並び替えについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
matukikun
記事: 9
登録日時: 6年前

配列の並び替えについて

#1

投稿記事 by matukikun » 6年前

龍神録ではなく学校の課題なのですが「
1.数字を読み込むごとに, それまでに入力された数値が格納された配列の最後の要素から, 先頭に向かって順に大小の比較を行う. これにより、読み込んだ数字が入るべき位置がわかる.
2.読み込んだ数字が入るべき箇所を空けるために、 既に記憶されている配列の要素のうち、 この数字よりも大きな数字をひとつ後ろにずらす。 空いた箇所に読み込んだ数字を代入する.
3.次に入力される数字の処理へ移る.また0が入力されると終了。
正整数: 17
正整数: 3
正整数: 9
正整数: 4
正整数: 0
入力された整数は小さい順に 0, 3, 4, 9, 17 です.」
となればよいのですが自分のコードでは
入力するとそのまま並び替えられずに表示されてしまいます。
何か間違いに気づいた方、またこういうやり方ならもっと効率がいいなど教えてくれる方がいましたらよろしくお願いします。

コード:

#include<stdlib.h>
#include<stdio.h>
#define buffer 256

int main(){
	//変数定義
	int x[501];
	int i=0,k,j;
	char buf[buffer];
	while(1){
		printf("正の整数: ");
		//変数に値の代入
		fgets(buf,buffer,stdin);
			x[i]=atoi(buf);
		//後ろから判別を繰り返す
		for(k=i;k>0;k--){
			//小さいかどうか判別
			if(x[i]<=x[k]){
				for(j=i;j>=k+1;j--){
					//要素を後ろにずらす
					x[j+1]=x[j];
						}
					//値を代入
					x[k+1]=x[i];
			 //for文から抜ける
			 break;
					}
				}
	if(x[i]==0)break;
	i++;

	}
	printf("入力された整数は小さい順に");
	for(k=0;k<=i-1;k++){
		printf(" %d,",x[k]);
	}
	printf(" %d です",x[i]);
	return 0;
}

アバター
usao
記事: 1564
登録日時: 6年前

Re: 配列の並び替えについて

#2

投稿記事 by usao » 6年前

うまくいかないときは,まず,現状コードがどう動くかを自分で確かめてみるべきです.
デバッガなどが使えれば楽ですが,ここでは,頭から順に自分で処理を追ってみましょう.

line8 : まず,i=0です.
(変数名をちゃんと役割に合ったものにすると読みやすいと思います.i → nInputed とか)
 ↓
line14 : 最初のデータを読み込むとx[0]にその値が入ります
line16 : このforの中には今回は入りません
line30 : i=1になります.
 ↓
line14 : 2番目のデータを読み込み,x[1]にその値が入ります.
line16 : k=1でループ内処理に入ります
line18 : i==kであるため,このifの条件は必ず満たされます

この時点で,本来,「2番目のデータ値は,最初のデータ値と比較されるべき」なのに
それがされていないことがわかります.


#あと,0が入力されたら終了ということですが,その0も「入力されたデータ値」に加えているように見えます.
 それでよいのでしょうか?

box
記事: 1739
登録日時: 9年前

Re: 配列の並び替えについて

#3

投稿記事 by box » 6年前

間違いに気づいたわけではありませんが、どうもインデントが乱れているようで、
コードが見づらいです。
コードが見やすいと、多少は間違いに気づきやすくなるような気がします。
なお、ロジック自体には何も手を触れていないことを申し添えます。

コード:

#include <stdlib.h>
#include <stdio.h>

#define buffer 256
 
int main(void)
{
    //変数定義
    int x[501];
    int i = 0, k, j;
    char buf[buffer];
    
    while (1) {
        printf("正の整数: ");
        
        //変数に値の代入
        fgets(buf, buffer, stdin);
        x[i]=atoi(buf);
        
        //後ろから判別を繰り返す
        for (k = i; k > 0; k--) {
            //小さいかどうか判別
            if (x[i] <= x[k]) {
                for (j = i; j >= k + 1; j--) {
                    //要素を後ろにずらす
                    x[j+1] = x[j];
                }
                //値を代入
                x[k+1] = x[i];
                //for文から抜ける
                break;
            }
        }
        if (x[i] == 0)
            break;
        i++;
    }
    
    printf("入力された整数は小さい順に");
    for (k = 0; k <= i-1; k++) {
        printf(" %d,", x[k]);
    }
    printf(" %d です", x[i]);
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

matukikun
記事: 9
登録日時: 6年前

Re: 配列の並び替えについて

#4

投稿記事 by matukikun » 6年前

usaoさん返信ありがとうございます。
コードを1から追いながらしっかりと紙に書いて考えていくと、何とか解決できました。
0についての質問に返答しないままで申し訳ありません。
本当にありがとうございました。

matukikun
記事: 9
登録日時: 6年前

Re: 配列の並び替えについて

#5

投稿記事 by matukikun » 6年前

boxさん返信ありがとうございます。
インデント、正直自分では十分と思っていました。
見やすいプログラムを勉強しなおすことにします。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る