ポインタ ソート

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

ポインタ ソート

#1

投稿記事 by tara » 6年前

数値をいくつか読み込んで降順に並び替えるプログラムを作ったのですがうまくいきません。
条件として
・バブルソートを使うこと
・入力データはdouble型の配列で、この配列を並び替えて表示させる
・要素数nであるdouble型の配列dataの要素を降順にソートする以下のような関数を添字演算子を用いずに作成し、これを用いること。void descending_sort(double *data,int n)
・ポインタxとyが指すオブジェクトの値を交換する以下のような関数を作成し、これをdescending_sortで用いること。
void swap(double *x, double *y)

これらの4つです

コンパイルは通るのですが数値を打ち込んだ後、エラーが出て強制終了してしまいます。
また、条件の3つ目と4つ目がよくわからないので無視してソースコードを作ってしまいました。
これらを修正してくださると助かります。
よろしくお願いいたします

//以下ソースコードです

#include<stdio.h>
#define NUMBER 10
void descending_sort(double *data,int n)
{
int a,b,temp;
for(a=0;a<(n-1);a++){
for(b=(n+1);b<n;b++){
if(data[a]<data){
temp=data[a];
data[a]=data;
data=temp;
}
}
}
}

int main(void)
{
int data[NUMBER],i,j,n=NUMBER;
printf("%d個の数値を入力してください\n",NUMBER);
for(j=0;j<NUMBER;j++){
printf("data[%d]: ",j);
scanf("%lf",&data[j]);
}
void descending_sort(data,n);
for(i=0;i<10;i++){
printf("data[%d]: %f\n",i,data);
}
return 0;
}

box
記事: 2002
登録日時: 13年前

Re: ポインタ ソート

#2

投稿記事 by box » 6年前

こんな感じなんでしょうか。

コード:

#include <stdio.h>

#define NUMBER (10)

void swap(double *x, double *y)
{
    double t;

    t = *x, *x = *y, *y = t;
}

void descending_sort(double *data, int n)
{
    int i, j;

    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            if (*(data + i) > *(data + j)) {
                swap(data + i, data + j);
            }
        }
    }
}

int main(void)
{
    double data[NUMBER];
    int i;

    printf("%d個の数値を入力してください\n", NUMBER);
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]: ", i);
        scanf("%lf", &data[i]);
    }
    descending_sort(data, NUMBER);
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]=%f\n", i, data[i]);
    }
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: ポインタ ソート

#3

投稿記事 by かずま » 6年前

tara さんが書きました: コンパイルは通るのですが数値を打ち込んだ後、エラーが出て強制終了してしまいます。
また、条件の3つ目と4つ目がよくわからないので無視してソースコードを作ってしまいました。
main関数の中で、
・data は、int の配列ではなく、double の配列にしましょう。
・descending_sort の定義には void を付けますが、
 呼び出しには void を付けてはいけません。

descending_sort関数の中で、
・b=(n+1) だと最初から b<n の条件が成り立たちません。
 for (b = n-1; b > 0; b--) { にして、
data[b-1] と data を比較して交換しましょう。

以上の間違いを修正したプログラムを貼り付けてくれれば、
残りの条件を満たすような修正方法をお教えしましょう。

box
記事: 2002
登録日時: 13年前

Re: ポインタ ソート

#4

投稿記事 by box » 6年前

Oops!
昇順と降順を間違えてた。sort関数で、不等号の向きを逆にしてください。>質問者様
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: ポインタ ソート

#5

投稿記事 by かずま » 6年前

box さんが書きました:こんな感じなんでしょうか。
・バブルソートではなく、選択ソートになっています。
・降順ではなく、昇順になっています。

tara
記事: 5
登録日時: 6年前

Re: ポインタ ソート

#6

投稿記事 by tara » 6年前

皆さんありがとうございます。
一応下のようなソースコードなら実行結果としては正しく出てきましたが、
やはり条件の3つ目と4つ目がよくわかりません。
box様が回答してくださったもののように、swapの中で並べ替えを行うのがよさそうですが、
いまいちやっていることがわかりません。
解説をお願いします。

コード:

#include<stdio.h>
#define NUMBER 10
void descending_sort(double *data,int n)
{
	int a,b,temp;
	for(a=0;a<(n-1);a++){
		for(b=(n-1);b>0;b--){
			if(data[b-1]>data[b]){
				temp=data[b];
				data[b]=data[b-1];
				data[b-1]=temp;
			}
		}
	}
}

int main(void)
{
	double data[NUMBER];
	int i,j,n=NUMBER;
	printf("%d個の数値を入力してください\n",NUMBER);
	for(j=0;j<NUMBER;j++){
		printf("data[%d]: ",j);
		scanf("%lf",&data[j]);
	}
	descending_sort(data,n);
	for(i=0;i<10;i++){
		printf("data[%d]: %f\n",i,data[i]);
	}
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ポインタ ソート

#7

投稿記事 by みけCAT » 6年前

tara さんが書きました:・要素数nであるdouble型の配列dataの要素を降順にソートする以下のような関数を添字演算子を用いずに作成し、これを用いること。void descending_sort(double *data,int n)
a[n]は(*((a) + (n)))と書き換えることができるので、機械的に書き換えればいいはずです。
tara さんが書きました:・ポインタxとyが指すオブジェクトの値を交換する以下のような関数を作成し、これをdescending_sortで用いること。
void swap(double *x, double *y)

コード:

				temp=data[b];
				data[b]=data[b-1];
				data[b-1]=temp;
という場所でdataとdata[b-1]の値の交換を行っているので、ここをうまくswap関数の呼び出しに置き換えるといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: ポインタ ソート

#8

投稿記事 by かずま » 6年前

tara さんが書きました: 一応下のようなソースコードなら実行結果としては正しく出てきましたが、
正しいとは思えません。

コード:

10個の数値を入力してください
data[0]: 3.14
data[1]: 1.5
data[2]: 9.2
data[3]: 6.5
data[4]: 3.5
data[5]: 8.9
data[6]: 7.9
data[7]: 3.2
data[8]: 3.8
data[9]: 4.6
data[0]: 1.000000
data[1]: 3.000000
data[2]: 3.000000
data[3]: 3.000000
data[4]: 3.140000
data[5]: 4.000000
data[6]: 6.000000
data[7]: 7.000000
data[8]: 8.000000
data[9]: 9.200000
・昇順になっている。
 比較の不等号の向きを元に戻しましょう。
・小数点以下が消えているものがある。
 temp を double にしましょう。

あと気になったのは、テストの時、10個データを入れる
のはしんどいので、#define NUMBER 4 としても、最後に
i<10 と書いてあって、うまくいきません。
10 の代わりに NUMBER または n と書きましょう。

浮動小数点数の表示は、%f より、%g の方が私は好きです。

それから、for (b = n - 1; b > 0; b--) にするように
アドバイスしましたが、b > 0 より b > a の方が
よかったのにうっかりしていました。

ということで、

コード:

#include <stdio.h>

#define NUMBER 4

void swap(double *x, double *y)
{
    double temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

void descending_sort(double *data, int n)
{
    int a, b;
    for (a = 0; a < n - 1; a++) {
        for (b = n - 1; b > a; b--) {
            if (data[b - 1] < data[b]) {
                swap(&data[b-1], &data[b]);
            }
        }
    }
}

int main(void)
{
    double data[NUMBER];
    int i;
    printf("%d個の数値を入力してください\n", NUMBER);
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]: ", i);
        scanf("%lf", &data[i]);
    }
    descending_sort(data, NUMBER);
    puts("---");
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]: %g\n", i, data[i]);
    }
    return 0;
}
あとは、添え字演算子 [ ] を使わないという条件ですね。

data は、*(data +i) と書き換えでき、
&data は、(data +i) と書き換えできます。

これにしたがって、descending_sort も main も
書き換えを行って、結果を貼り付けてください。

そうすれば、swap の解説もしましょう。

tara
記事: 5
登録日時: 6年前

Re: ポインタ ソート

#9

投稿記事 by tara » 6年前

遅くなってすみません。
ありがとうございます。
こういうことでしょうか?
いまいち違うような気がしますが…
また、main関数内で, data[NUMBER]を定義するときも*(data+NUMBER)とするのでしょうか?
そうするとうまくいかないのですが…

コード:

#include<stdio.h>
#define NUMBER 10
void swap(double *x,double *y)
{
	double temp;
	temp=*x;
	*x=*y;
	*y=temp;
}
void descending_sort(double *data,int n)
{
	int a,b,temp;
	for(a=0;a<(n-1);a++){
		for(b=(n-1);b>a;b--){
			if(*(data+(b-1))<*(data+b)){
				swap(data+(b-1),data+b);
			}
		}
	}
}

int main(void)
{
	double data[NUMBER];
	int i,j,n=NUMBER;
	printf("%d個の数値を入力してください\n",NUMBER);
	for(j=0;j<NUMBER;j++){
		printf("data[%d]: ",j);
		scanf("%lf",(data+j));
	}
	descending_sort(data,n);
	for(i=0;i<NUMBER;i++){
		printf("data[%d]: %f\n",i,*(data+i));
	}
	return 0;
}

かずま

Re: ポインタ ソート

#10

投稿記事 by かずま » 6年前

tara さんが書きました: また、main関数内で, data[NUMBER]を定義するときも*(data+NUMBER)とするのでしょうか?
宣言「double data[NUMER];」の中の [ ] は、
添字演算子ではなく、配列宣言子の一部です。
double *(data + NUMBER); という宣言はありません。
tara さんが書きました: こういうことでしょうか?
いまいち違うような気がしますが…
まず、条件では、descending_sort に添字演算子を使うなと言っていて、
main は使ってもいいみたいですね。

次に、data を *(data + i) に置き換えるのは機械的にできて、
添字演算子を使うなという条件は、一応満たしているのですが、
これでは、添字演算子を使うのと同じで、あまり意味がありません。

出題者の意図は、配列の要素を添字で参照するのではなく、
ポインタで参照してほしいということなんだろうと、私は思います。

すなわち、次のようなプログラムを書くことを期待している
のではないでしょうか?

コード:

#include <stdio.h>

#define NUMBER 4

void swap(double *x, double *y)
{
    double temp;

    temp = *x;
    *x = *y;
    *y = temp;
}

void descending_sort(double *data, int n)
{
    double *last, *curr, *prev;

    for (last = data + n - 1; data < last; data++) {
        for (curr = last; curr > data; curr--) {
            prev = curr - 1;
            if (*prev < *curr) swap(prev, curr);
        }
    }
}

int main(void)
{
    double data[NUMBER];
    int i;
    printf("%d個の数値を入力してください\n", NUMBER);
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]: ", i);
        scanf("%lf", &data[i]);
    }
    descending_sort(data, NUMBER);
    puts("---");
    for (i = 0; i < NUMBER; i++) {
        printf("data[%d]: %g\n", i, data[i]);
    }
    return 0;
}
swap の解説はちょっと待ってください。
具体的に何が分かりませんか?

tara
記事: 5
登録日時: 6年前

Re: ポインタ ソート

#11

投稿記事 by tara » 6年前

遅くまでありがとうございます
一応かずま様が提示してくれたソースコードまでは出来ました。
ところで、swap関数内で行っていることは、私が2回目に貼ったソースコードの9行目から11行目までと同じことですか?
そうであれば理解しました。

かずま

Re: ポインタ ソート

#12

投稿記事 by かずま » 6年前

tara さんが書きました: ところで、swap関数内で行っていることは、私が2回目に貼ったソースコードの9行目から11行目までと同じことですか?
そうであれば理解しました。
そうです。同じです。

コード:

void swap(double x, double y)
{
    double temp;

    temp = x;
    x = y;
    y = temp;
}
このように定義し、次のように呼び出すと
なぜうまくいかないかを理解していれば十分です。

コード:

    swap(data[b-1], data[b]);
解決にチェックを入れて送信をお願いします。

tara
記事: 5
登録日時: 6年前

Re: ポインタ ソート

#13

投稿記事 by tara » 6年前

皆さん本当に何度もありがとうございました。
まだまだc言語については初学者同然ですが、頑張っていきたいと思います。

返信

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