2016-07-07 2 views
1

私はCでクイックソートを使用しようとしています。私のプログラムは、コマンドライン引数(name1 age1 name2 age2 ...など)前記年齢を降順に出力する。クイックソート機能は、最後の値が最大の場合にのみ有効です

最後に入力した年齢が一番大きい場合のみ正しく動作します。それ以外は出力もSeg Faultもありません11.誰にもアイデアはありますか?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define NameLen 80 
void print_struct(); 

struct people 
{ 
char name [NameLen + 1]; 
int age; 
}; //defining a structure// 

typedef struct people PERSON; 
void quicksort(struct people list[],int,int); 
int main(int argc, const char * argv[]) 

{ 
int i,j; 
j = 0; 
int l = ((argc/2)-1); 


struct people list[l]; //maximum size of array of structs 


    if (argc %2 == 0) //if the number of arguments is an even number 
{ 

printf("Invalid Arguments!\n"); 
printf("Usage : ./hw5 name1 age1 name2 age2 ... "); //print error message and correct program usage 
    exit(0); 
} 

printf("You have entered %d persons(s) into the program \n",(argc/2)); 

for (i=1; i < argc; i+=2) 

{ 
    strcpy(list[j].name, argv[i]); 
    list[j].age = atoi(argv[i+1]); 
    if(list[j].age == 0) 
    { 
     printf("...Invalid age <=0. Try again.\n"); 

     exit(0); 
    } 
    j++; 

} 
    printf("Unsorted Names: \n"); 
    print_struct(&list,argc); 

printf ("Sorted by Age: \n"); 
quicksort(list,0 ,j); 
for(i=0;i<j;i++){ 
    printf("Name : %s| Age : %d\n", list[i].name, list[i].age);}//possible error here? 

//Quicksort Function 
+0

一貫性のあるコードのスタイルを維持することは間違いなく、読みやすさを改善します。 – Kupiakos

+0

ありがとう@Kupiakos!これは私の2回目の投稿ですので、私はそれに取り組んでいきます! – QuesionableCode

+0

1)コードを一貫してインデントする2)一貫した垂直スペーシングを使用する3)公理に従う:* 1行につき1つのステートメントとステートメントごとに1つの変数宣言を書く* – user3629249

答えて

2

おそらく問題はjの値です。 jはリストの長さですか?またはリストの長さ - 1?

あなたが望むものをだろう。このように思える:リスト

printf ("Sorted by Age: \n"); 
quicksort(list,0 ,j-1); 
for(i=0;i<j;i++){ 
    printf("Name : %s| Age : %d\n", list[i].name, list[i].age);} 
+0

これも前に試しました!幸運なし。 Segフォールトをまだ得ている! – QuesionableCode

+0

その場合、もっとコードを共有できますか?私はエラーを再現できませんでした。 – MAS

+0

確かに!私はそれをすべて以下に掲載します!ありがとうございます@MAS – QuesionableCode

0

の J =長さがクイックソート機能で結構です。

quicksort(list,0 ,j); 

あなたはfirstlastためで渡している値は、最初と最後の要素のインデックスを表します。問題は、あなたが間違ってそれを呼んでいるということです。 jを使用して要素をループする方法から明らかなように、jは要素の数です。つまり、最後の要素はインデックスj-1です。

したがって、lastの値は配列の最後の1つの要素です。この偽の要素を読み書きしようとすると、undefined behaviorが呼び出され、あなたの場合(幸いにも)セグメンテーションが発生します。

最後の要素の実際のインデックス(つまりサイズよりも小さいもの)を渡し、正常に実行されます。

quicksort(list,0 ,j - 1); 
0

あなたのループが正しくありません:

while(list[i].age<=list[pivot].age&&i<last) 
     i++; 

あなたは、配列の範囲外になる値を、交換しようとしているため、このループは悪いですi == last、で終わるすることが可能です。ここで

while(list[j].age>list[pivot].age) 
     j--; 

lastとしてj開始以来、あなたは右の配列の外に読んでオフを開始。

可能性のある救済策の1つは、jを先に移動し、次にテスト(do- whileスタイル)です。次に、iをインクリメントし、デクリメントされたjに対してテストします。

do --j; while(list[j].age>list[pivot].age); 
    do ++i; while(list[i].age<=list[pivot].age&&i<j); 
+0

ありがとうございます@jxh私はSeg Faultの問題を解決するあなたの戦略を暗示しましたが、それでも正しくソートすることはできません。 :( – QuesionableCode

0

コードを少しシンプルにしました(できるだけシンプルにするため、文字の配列をcharに変更しました)。 私の考えは、あなたが呼び出すときということです:あなたが呼び出す必要がありますすることはあり

quicksort(list,0 ,j); 

quicksort(list,0 ,j-1); 

最後のパラメータが配列な長さマイナス1、最後の位置でなければならないので。

コードを実行しているときにseg faultが発生していないか、または可能ならば私が修正したものが入力として使用している文字列を再確認します。

コードの "私の"バージョンです。

希望します。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define NameLen 80 
void print_struct(); 

struct people 
{ 
    char name; 
    int age; 
}; //defining a structure// 

typedef struct people PERSON; 
void quicksort(struct people list[],int,int); 

int main(int argc, const char * argv[]) 
{ 
    int i,j; 
    j = 10; 
    struct people list[10]; //maximum size of array of structs 

    for (i=0; i < 10; i++) 
    { 
     list[i].name = 'a'; 
     list[i].age = 10-i; 
    } 

    printf("Unsorted Names: \n"); 
    for(i=0;i<j;i++){ 
     printf("Name : %c| Age : %d\n", list[i].name, list[i].age);}//possible error here? 

    printf ("Sorted by Age: \n"); 
    quicksort(list,0 ,j-1); 
    for(i=0;i<j;i++){ 
     printf("Name : %c| Age : %d\n", list[i].name, list[i].age);}//possible error here? 
} 

void quicksort(struct people list[],int first,int last) 
{ 
    struct people temp; 
    int i,j,pivot; 

    if(first<last){ 
     pivot=first; 
     i=first; 
     j=last; 

     while(i<j) 
     { 
      while(list[i].age<=list[pivot].age&&i<last) 
       i++; 
      while(list[j].age>list[pivot].age) 
       j--; 
      if(i<j){ 
       temp=list[i]; 
       list[i]=list[j]; 
       list[j]=temp; 
      } 
     } 

    temp=list[pivot]; 
    list[pivot]=list[j]; 
    list[j]=temp; 
    quicksort(list,first,j-1); 
    quicksort(list,j+1,last); 
    } 
} 
0

すべてのコメントを適用した後、これはきれいにコンパイルされたコード、ですが、原因2つの不足している機能にリンクしません:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define NAME_LEN (80) 


struct people 
{ 
    char name [NAME_LEN + 1]; 
    int age; 
}; //defining a structure// 

typedef struct people PERSON; 

// print_struct(ptrToList, numElements) 
void print_struct(PERSON *, int); 

// quicksort(ptrToList, firstOffset, numElements) 
void quicksort(struct people list[],int,int); 


int main(int argc, const char * argv[]) 
{ 
    //int i,j; 
    //j = 0; 
    //int l = ((argc/2)-1); 
    int l = argc/2; 

    struct people list[l]; //maximum size of array of structs 

    if (argc %2 == 0) //if the number of arguments is an even number 
    { 
     //printf("Invalid Arguments!\n"); 
     fprintf(stderr, "Invalid Arguments!\n"); 

     //printf("Usage : ./hw5 name1 age1 name2 age2 ... "); //print error message and correct program usage 
     fprintf(stderr, "Usage : %s name1 age1 name2 age2 ... ", argv[0]); 

     // exit(0); 
     exit(EXIT_FAILURE); 
    } 

    //printf("You have entered %d persons(s) into the program \n",(argc/2)); 
    printf("You have entered %d persons(s) into the program \n", l); 

    //for (int i=1; i < argc; i+=2) 
    for (int i=1, j=0; j < l; i+=2, j++) 
    { 
     //strcpy(list[j].name, argv[i]); 
     memset(list[i].name, '\0', NAME_LEN+1); 
     strncpy(list[j].name, argv[i], NAME_LEN); 
     list[j].age = atoi(argv[i+1]); 

     if(list[j].age == 0) 
     { 
      fprintf(stderr, "...Invalid age <=0. Try again.\n"); 

      //exit(0); 
      exit(EXIT_FAILURE); 
     } 
     //j++; 
    } 

    printf("Unsorted Names: \n"); 
    //print_struct(&list,argc); 
    print_struct(list, l); 

    //printf ("Sorted by Age: \n"); 
    //quicksort(list,0 ,j); 
    quicksort(list, 0, l); 

    printf ("Sorted by Age: \n"); 
    // //for(i=0;i<j;i++) 
    //for(int i=0; i<l; i++) 
    //{ 
    // printf("Name : %s| Age : %d\n", list[i].name, list[i].age); 
    //}//possible error here? 
    //} 
    print_struct(list, l); 
} // end function: main 


//Quicksort Function