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

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

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

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

アルゴリズム

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Q&A

解決済

4回答

3321閲覧

double配列のクイックソート

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

アルゴリズム

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

0グッド

1クリップ

投稿2019/09/02 10:22

編集2019/09/04 09:47

196個の要素のあるdouble配列をクイックソートで大きい順に並べようとしています.しかし,実行するとsegmentation fault が起こります.常に起こるわけでもなく,上手く行くときもあるのですが,その時もどうも惜しい感じで,完全にソートされません.実はソートは自分で組む気は無く,インターネットで漁ったものを利用したのですが,segmentation faultが起こったので,quick_sort関数のifの条件式を left<right から (right-left)>1 と変えたのですが,やはりそれが完全にソートされない原因でしょうか.

コード必要な部分のみ記述します.

呼び出し部分も追記します.
eigenValとeigenVec[]が1対1対応で,eigenVec[]も一緒にソートされて欲しいためにsortIndex[]は置いています.

C

1#define CTGRY 46 2#define FTRDIM 196 3 4void swap (double *x, double *y) { 5 double temp; 6 7 temp = *x; 8 *x = *y; 9 *y = temp; 10} 11 12int partition (double *array, int left, int right,int *sortIndex) { 13 int i, j, pivot; 14 i = left; 15 j = right + 1; 16 pivot = left; 17 18 do{ 19 do { i++; } while (array[i] > array[pivot] ); 20 do { j--; } while (array[pivot] > array[j] ); 21 22 if (i < j) { 23 swap(&array[i], &array[j]); 24 sortIndex[i]=j; 25 sortIndex[j]=i; 26 } 27 }while(i<j); 28 29 swap(&array[pivot], &array[j]); 30 sortIndex[pivot]=j; 31 sortIndex[j]=pivot; 32 33 return j; 34} 35 36void quick_sort (double *array, int left, int right,int *sortIndex) { 37 int pivot; 38 39 if (right>left) { 40 pivot = partition(array, left, right,sortIndex); 41 quick_sort(array, left, pivot-1,sortIndex); 42 quick_sort(array, pivot+1, right,sortIndex); 43 } 44} 45 46void ReadEigenVV( double EigenVal[CTGRY][FTRDIM], double EigenVec[CTGRY][FTRDIM][FTRDIM] ) 47{ 48 FILE *fp; 49 int sortIndex[FTRDIM]; 50 fp=fopen(EIGENVV,"r"); 51 if(fp==NULL){ 52 printf("cannot open %s",EIGENVV); 53 exit(0); 54 } 55 int i,j,k; 56 for(i=0;i<FTRDIM;i++) sortIndex[i]=i; 57 58 for(i=0;i<CTGRY;i++){ 59 for(j=0;j<FTRDIM;j++) 60 fscanf(fp,"%lf",&EigenVal[i][j]); 61 62 quick_sort(EigenVal[i],0,FTRDIM-1,sortIndex); 63 64 for(j=0;j<FTRDIM;j++) 65 for(k=0;k<FTRDIM;k++) 66 fscanf(fp,"%lf",&EigenVec[i][sortIndex[j]][k]); 67 68 for(j=0;j<FTRDIM;j++) 69 printf("%d:%lf\n",j,EigenVal[i][j]); 70 71 } 72 73}

qsortを使ってみてはとの提案があったのでその方法でも書いてみましたが,こちらはこちらでsegmentation faultは起きてしまいます...

c

1#define EIGENVV "eigenvv.dic" 2#define CTGRY 46 3#define FTRDIM 196 4 5typedef struct 6{ 7 double eigenVal; 8 double eigenVec[FTRDIM]; 9}eigenSet; 10 11 12int compare(const void *a,const void *b){ 13 double A= ((eigenSet *)b)->eigenVal; 14 double B= ((eigenSet *)a)->eigenVal; 15 16 if(A>B){ 17 return -1; 18 }else if(A<B){ 19 return 1; 20 }else{ 21 return 0; 22 } 23} 24 25void ReadEigenVV( double EigenVal[CTGRY][FTRDIM], double EigenVec[CTGRY][FTRDIM][FTRDIM] ) 26{ 27 FILE *fp; 28 fp=fopen(EIGENVV,"r"); 29 if(fp==NULL){ 30 printf("cannot open %s",EIGENVV); 31 exit(0); 32 } 33 int i,j,k; 34 eigenSet eSet[FTRDIM]; 35 36 for(i=0;i<CTGRY;i++){ 37 for(j=0;j<FTRDIM;j++) 38 fscanf(fp,"%lf",&EigenVal[i][j]); 39 for(j=0;j<FTRDIM;j++) 40 eSet[j].eigenVal=EigenVal[i][j]; 41 42 for(j=0;j<FTRDIM;j++) 43 for(k=0;k<FTRDIM;k++) 44 fscanf(fp,"%lf",&EigenVec[i][j][k]); 45 for(j=0;j<FTRDIM;j++) 46 for(k=0;k<FTRDIM;k++) 47 eSet[j].eigenVec[k]=EigenVec[i][j][k]; 48 49 50 qsort(eSet,FTRDIM,FTRDIM*sizeof(eigenSet),compare); 51 52 for(j=0;j<FTRDIM;j++) 53 EigenVal[i][j]=eSet[j].eigenVal; 54 for(j=0;j<FTRDIM;j++) 55 for(k=0;k<FTRDIM;k++) 56 EigenVec[i][j][k]=eSet[j].eigenVec[k]; 57 58 for(j=0;j<FTRDIM;j++) 59 printf("%d:%lf\n",j,EigenVal[i][j]); 60 61 } 62 63}

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

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

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

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

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

guest

回答4

0

ベストアンサー

実はソートは自分で組む気は無く,

であれば、qsort()関数を使いましょう。要素の比較関数を書いて、引数に渡すだけです。

man qsortより:

C

1#include <stdlib.h> 2 3void qsort(void *base, size_t nmemb, size_t size, 4 int (*compar)(const void *, const void *));

投稿2019/09/02 10:29

otn

総合スコア84553

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

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

0

qsortを使ってみてはとの提案があったのでその方法でも書いてみましたが,こちらはこちらでsegmentation faultは起きてしまいます...

C

1 qsort(eSet,FTRDIM,FTRDIM*sizeof(eigenSet),compare);

qsort関数第3引数は全体サイズでなく一つの要素のサイズです。この場合はsizeof(eigenSet)です。FTRDIM*の部分がいりません。

投稿2019/09/04 12:15

nomuken

総合スコア1627

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

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

0

次のように、index も swap しないといけないのではありませんか?

C

1void swap2(int *x, int *y) { int t = *x; *x = *y; *y = t; } 2 3 swap(&array[i], &array[j]); 4 swap2(&sortIndex[i], &sortIndex[j]); 5 } 6 }while(i<j); 7 8 swap(&array[pivot], &array[j]); 9 swap2(&sortIndex[pivot], &sortIndex[j]);

そうでないと、quick_sort を呼び出した後の sortIndex には、
重複する値があり、無くなっている値もあります。
そうすると、EigenVec には値が入らないところが出てきます。

どこで Segmentation fault が起こるのか、デバッガーで分かりませんか?

投稿2019/09/04 11:54

kazuma-s

総合スコア8224

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

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

0

quick_sort の呼び出しはどうなっていますか?

C

1 double array[FTRDIM]; 2 int sortIndex[FTRDIM]; 3 4 quick_sort(array, 0, FTRDIM - 1, sortIndex);

right には、ちゃんと FTRDIM -1 を与えていますか?
sortIndex には FTRDIM個の要素がありますか?

投稿2019/09/02 19:46

kazuma-s

総合スコア8224

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問