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

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

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

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Q&A

解決済

2回答

1396閲覧

クイックソート実行時のエラー原因が分からない

1noino

総合スコア10

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

0グッド

0クリップ

投稿2022/06/25 22:13

クイックソートの実装をしようとしています。
実行時にエラー(atcoderのコードテストだと終了コード139)になるのですが、エラー文が出てこず、原因(どこをどう直せばよいか)が分かりません。

環境はwindowsでエディターとしてVScodeを使用しています。
コードは以下の通りで、main直前の「quick_sort(A+j, n);」をコメントアウトすると正しくソートはできていないものの、終了はする(printfが実行されている)ので問題は「quick_sort(A+j, n);」にあるのではないかと考えています。

不足している情報や不明点があれば追記しますので指摘してください。
よろしくお願いします。

GCC

1#include <stdio.h> 2#include <assert.h> 3 4// 素数 5#define N 2999 6 7int A[N]; 8 9// *p と *q の値を入れ替える関数 10void swap(int *p, int *q){ 11 int tmp; 12 tmp = *p; 13 *p = *q; 14 *q = tmp; 15} 16 17 18/* 19A[0], A[1], ..., A[n-1] の中でk+1番目に小さい値を返す関数 20ただし、Aの中身は書き換えてしまう。 21*/ 22 23void quick_sort(int A[], int n){ 24 int i, j, pivot; 25 26 if (n > 1){ 27 // 真ん中の要素をピボットとする 28 pivot = A[n/2]; 29 A[n/2] = A[0]; 30 A[0] = pivot; 31 32 for(i = j = 1; i < n; i++){ 33 //pivot以下の数字をA[i]からA[j-1]に集約 34 if (A[i] <= pivot){ 35 swap(A+i, A+j); 36 j++; 37 } 38 } 39 40 //pivotと一致するものを中心に寄せる 41 //pivot=3なら[2, 1, 2, 3, 3, 3, …, 3, 3, 5, 6, 5, 7]のようにする 42 int x, y, piv_num; // x:走査用, y;置換用 43 piv_num = 0; 44 45 for (x = y = j-1; x>=0; x--){ 46 if (A[x] == pivot){ 47 swap(A+x, A+y); //位置xにあったpivotに一致する数字を位置yに寄せる 48 y--; 49 piv_num++; 50 } 51 } 52 53 //A[j-piv_num]からA[j-1]までの連続したpiv_num個がpivotと一致する数字 54 quick_sort(A+0, j-piv_num); 55 quick_sort(A+j, n); 56 } 57} 58 59int main(){ 60 int i; 61 A[0] = 0; 62 A[1] = 17; //原始元 63 for(i=2;i<N;i++){ 64 A[i] = (long long int) A[i-1] * A[1] % N; 65 } 66 67// すべての要素が同じ場合でも計算が早く終わるか確認する 68 69 quick_sort(A, N); 70 for(i=0;i<N;i++){ 71 if(A[i] != i) printf("ERROR %dth element is %d\n", i, A[i]); 72 } 73} 74

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

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

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

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

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

hoshi-takanori

2022/06/25 23:13

quick_sort(A+j, n); は配列の何番目から何個の要素をソートしますか?
1noino

2022/06/25 23:24

quick_sort(A+j, n)は「配列Aのj+1番目(A[j])から配列のn番目(A[n-1])までをsortする関数」として実装したつもりです。
melian

2022/06/26 00:13

quick_sort(A+j, n); => quick_sort(A+j, n-j);
hoshi-takanori

2022/06/26 00:16

つもりなだけで、実際は j 番目から n 個の要素、つまり元の配列の A[j] 〜 A[j + n - 1] をソートしようとしてますね。
1noino

2022/06/26 01:29

まさにその通りでした。melian氏のコードのように書き直したところ、エラーはでませんでした。ありがとうございます。
guest

回答2

0

自己解決

quick_sort(A+j, k)は元の配列のA[j]からA[j+k-1]までをソートすることを理解していませんでした。そのため。

quick_sort(A+j, n);
=>
quick_sort(A+j, n-j);

のように書き換えるとエラーを回避できました。

投稿2022/06/26 01:30

1noino

総合スコア10

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

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

0

ざっと見て気のついたところを。

int i;
A[0] = 0;
A[1] = 17; //原始元

i は初期化されてません。
ローカル変数は初期化しないとデタラメの値もってます


あれ?quick_sort って再帰呼び出して終了しようがないんでは。
どういう条件でこの関数は終了するんでしょう

投稿2022/06/25 22:55

編集2022/06/26 00:18
y_waiwai

総合スコア87774

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

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

hoshi-takanori

2022/06/25 23:11

i は次の for 文で初期化されますよ。
y_waiwai

2022/06/26 00:08

ああ、1なのね。 見間違いしてました
Zuishin

2022/06/26 01:40 編集

> どういう条件でこの関数は終了するんでしょう 終了コード 139 と書いてあるので、セグメンテーション違反です。 https://atcoder.jp/contests/apg4b/tasks/APG4b_al https://shmug.hatenablog.com/entry/2020/12/15/235915 スタックオーバーフローを意図した回答だと思いますが、問題は他にあります。 そもそも、関数の実行条件が n > 1 なので、n <= 1 の場合はそれ以上再帰呼び出ししません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問