#7
by かずま » 7年前
MILE さんが書きました: ↑7年前
ただいま検証したところ、print3の記述だとエラーが出て検証することができませんでした 申し訳ないです…
(*list)
に関しては修正したらひとまず成功しました
というより、この記述選択ソート事態のコードがミスっていて昇順(降順)になっていませんね…大変申し訳ありませんでした
エラーが出るのは、print3 ではなく、print2 ですね。
また、配列を関数に渡すのは、print3 の (*list) でもできるけど、
通常は print のようにするのだということは理解されていますか?
選択ソート自体のコードミスは認められたようですが、
それはもう解決済みなのでしょうか?
参考までに、私のコードを示しますが、これは模範解答ではありません。
コード:
#include <stdio.h> // fgets, sscanf, printf, puts
#define SIZE 20
void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; }
void selection_sort(int *a, int n, int ascending)
{
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (ascending ? a[i] > a[j] : a[i] < a[j]) swap(a + i, a + j);
}
int input(int a, int b)
{
char buf[100];
while (fgets(buf, sizeof buf, stdin)) {
int n;
if (sscanf(buf, "%d", &n) == 1 && n >= a && n <= b) return n;
printf("規定内の数値ではありません。再入力をお願いします: ");
}
return -1;
}
int main(void)
{
int a[SIZE], n;
printf("選択ソートのプログラム\n"
"リストに入れる個数を入力してください\n" "3~%dが有効です: ", SIZE);
n = input(3, SIZE);
if (n < 0) return puts("入力エラー"), 1;
puts("ソートする数字を入力してください\n" "1~100まで有効です");
for (int i = 0; i < n; i++)
printf("%d個目の数字:", i + 1), a[i] = input(1, 100);
printf("どちらにソートするか選択してください。1:昇順 2:降順 ");
selection_sort(a, n, input(1, 2) == 1);
for (int i = 0; i < n; i++)
printf("%d\n", a[i]);
}
selection_code の中の if 文ですが、おそらく、
こんな書き方をする人はほとんどいないと思います。
普通は次のように書くでしょう。
コード:
if (ascending) {
if (a[i] > a[j]) swap(&a[i], &a[j]);
}
else {
if (a[i] < a[j]) swap(&a[i], &a[j]);
}
また、selection_sort自体、もう少し効率の良い書き方もできます。
コード:
void selection_sort(int *a, int n, int ascending)
{
for (int i = 0; i < n - 1; i++) {
int k = i;
for (int j = i + 1; j < n; j++)
if (ascending ? a[k] > a[j] : a[k] < a[j]) k = j;
swap(a + i, a + k);
}
}
j のループで何度も swap を呼び出すよりも、k = j; という単純な
処理で済まし、swap を呼ぶのは一度だけとしています。
問題を解くのに、解は一つではありません。いろいろ考えてみましょう。
[quote=MILE post_id=150428 time=1523276160 user_id=2682]
ただいま検証したところ、print3の記述だとエラーが出て検証することができませんでした 申し訳ないです…
(*list)[i]に関しては修正したらひとまず成功しました
というより、この記述選択ソート事態のコードがミスっていて昇順(降順)になっていませんね…大変申し訳ありませんでした[/quote]
エラーが出るのは、print3 ではなく、print2 ですね。
また、配列を関数に渡すのは、print3 の (*list) でもできるけど、
通常は print のようにするのだということは理解されていますか?
選択ソート自体のコードミスは認められたようですが、
それはもう解決済みなのでしょうか?
参考までに、私のコードを示しますが、これは模範解答ではありません。
[code]
#include <stdio.h> // fgets, sscanf, printf, puts
#define SIZE 20
void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; }
void selection_sort(int *a, int n, int ascending)
{
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (ascending ? a[i] > a[j] : a[i] < a[j]) swap(a + i, a + j);
}
int input(int a, int b)
{
char buf[100];
while (fgets(buf, sizeof buf, stdin)) {
int n;
if (sscanf(buf, "%d", &n) == 1 && n >= a && n <= b) return n;
printf("規定内の数値ではありません。再入力をお願いします: ");
}
return -1;
}
int main(void)
{
int a[SIZE], n;
printf("選択ソートのプログラム\n"
"リストに入れる個数を入力してください\n" "3~%dが有効です: ", SIZE);
n = input(3, SIZE);
if (n < 0) return puts("入力エラー"), 1;
puts("ソートする数字を入力してください\n" "1~100まで有効です");
for (int i = 0; i < n; i++)
printf("%d個目の数字:", i + 1), a[i] = input(1, 100);
printf("どちらにソートするか選択してください。1:昇順 2:降順 ");
selection_sort(a, n, input(1, 2) == 1);
for (int i = 0; i < n; i++)
printf("%d\n", a[i]);
}
[/code]
selection_code の中の if 文ですが、おそらく、
こんな書き方をする人はほとんどいないと思います。
普通は次のように書くでしょう。
[code]
if (ascending) {
if (a[i] > a[j]) swap(&a[i], &a[j]);
}
else {
if (a[i] < a[j]) swap(&a[i], &a[j]);
}
[/code]
また、selection_sort自体、もう少し効率の良い書き方もできます。
[code]
void selection_sort(int *a, int n, int ascending)
{
for (int i = 0; i < n - 1; i++) {
int k = i;
for (int j = i + 1; j < n; j++)
if (ascending ? a[k] > a[j] : a[k] < a[j]) k = j;
swap(a + i, a + k);
}
}
[/code]
j のループで何度も swap を呼び出すよりも、k = j; という単純な
処理で済まし、swap を呼ぶのは一度だけとしています。
問題を解くのに、解は一つではありません。いろいろ考えてみましょう。