質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

1回答

1744閲覧

入力された数字を並び替えるプログラムがうまく作動しない

Ryuuse

総合スコア27

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2019/06/15 12:07

編集2019/06/15 15:45

プログラミング初心者です。入力された数字に対し、昇順か降順に並び替えるプログラムを作っています。実行し、降順か昇順を選択する画面でそれぞれ指定した数字(前者なら0、後者なら1)を選び入力した後、最初に入力された数字が連続して表示されたままでした(例えば3、2、4であれば3,3,3とと表示されます)。他のやり方(max/minを使わない方法)では並び替えることに成功しましたが、max/minを用いた方法で作ることは可能なのでしょうか。もし分かりましたら教えてください。本は参考せずに独自で作り上げました。ソースコードは以下の通りです。

#include<stdio.h> #include<stdlib.h> #define swap(type, x, y) {type t=x; x=y; y=t;} void arrangeH(int a[], int n) { int max=a[0]; for(int i=0; i<n-1; i++){ for(int j=0; j<n; j++){ if(a[j]>max){ swap(int, a[j], max);} } max=a[i+1]; } } void arrangeL(int a[], int n) { int min=a[0]; for(int i=0; i<n-1; i++){ for(int j=0; j<n; j++){ if(a[j]<min){ swap(int, a[j], min);} } min=a[i+1]; } } int main() { int n; int *num; int i; printf("入力する数値の個数="); scanf("%d",&n );     num=calloc(n,sizeof(int)); printf("%d個の数値を入力してください\n", n); for(int i=0; i<n; i++){ scanf("%d",&num[i] ); } printf("降順(0)にしますか、昇順(1)にしますか。:"); int s; do{scanf("%d", &s); if(s==0){ arrangeH(num, n);} else if(s==1){ arrangeL(num, n);} }while(s!=0 && s!=1); for(int a=0; a<n; a++){ printf("%d\n", num[a]); } free(num); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2019/06/15 12:45

do - whileから抜ける条件がないからでは。
Ryuuse

2019/06/15 13:06

修正したところ、作動しましたが数字の並び替えはされていないままでした。
1T2R3M4

2019/06/15 15:10 編集

min/maxを使用しなくてもa[i]にmin/maxが入るようにすればいいのでは。 1周目(i=0) a[0]にa[0]~a[n-1]のmin/max値 2周目(i=1) a[1]にa[1]~a[n-1]のmin/max値  : n-1周目(i=n-2) a[n-2]にa[n-2]~a[n-1]のmin/max値 みたいな感じ。
Ryuuse

2019/06/15 15:40

回答ありがとうございます。確かに、max/minを使わずとも数列を並べることができることを、プログラムを修正し実行して確認しました。
guest

回答1

0

ベストアンサー

do-whileの条件式がおかしいです。

C

printf("降順(0)にしますか、昇順(1)にしますか。:");
...
do{
scanf("%d", &s);
...
}while(s!=0 || s!=1);

『sが0ではない、あるいはsが1ではない』という条件は恒真です。
正しくは『sが0ではない、尚且つsが1ではない』です。

C

1do { 2 ... 3} while(s!=0 && s!=1);

また次の部分も妙なコードになっています。

C

printf("num[%d]\n", a);

例えばaが0のときは num[0] と表示されてしまいます。

コードの書き方について

teratailには、コードを見やすく表示する機能があります。
質問編集画面を開き、コードを選択した状態で<code>ボタンを押して下さい。
C

投稿2019/06/15 12:49

編集2019/06/15 12:53
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ryuuse

2019/06/15 12:58

それがありましたね、単純なミスに気づきませんでした...
Ryuuse

2019/06/15 13:06

しかし数字の並び替えはされていないままでした...
LouiS0616

2019/06/15 13:23

ソート関数が正しく実装されていないのが原因でしょう。 特に max=a[i+1]; は iがn のとき配列の範囲外にアクセスしてしまいますよね。 --- 回答に書いてあるとおり、質問にはコードブロックを適用して下さい。 読みにくいです。
LouiS0616

2019/06/15 13:31

このソート関数はどんなアルゴリズムで組もうと思ったものでしょうか?バブルソートと選択ソート(in-place)が中途半端に混じっているような印象を受けます。
Ryuuse

2019/06/15 13:55

降順の場合、数列が「1,3、2」であれば、最大値(max)の初期値を先頭の1とし、1より大きい数字は入れ替えを行い、num[1]である3は1と入れ替え、maxは3となります。num[2]の2はmaxより小さいので入れ替えは行いません。その後maxがnum[1]になり,i=1のループ処理を行います。
LouiS0616

2019/06/15 14:00

なるほど、インプレースな選択ソートですね。 二つ問題があります。 ・ maxを決める際に範囲外アクセスが発生する (先に指摘したとおり) ・ swapマクロの使い方を間違えて居る 関数内でスワップが本当にできているかどうか確認してみて下さい。 ヒント: int a = b; のとき、aの値を書き換えてもbの値には影響しません。
LouiS0616

2019/06/15 14:10

もう一つ問題があるのを見逃していました。 ・ 配列の先頭の方のソート済みの部分を守れていない 毎回jを0からnまで回すと、常に最大値のみが捕捉されることになりますね。
LouiS0616

2019/06/15 14:12

なお質問の編集は私には通知が来ませんので、たまたま気付くか注視していない限り追記分に対してのアドバイスはできません。悪しからず。
Ryuuse

2019/06/15 14:18

回答ありがとうございます。できる限りやってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問