2012-03-12 21 views
1

私はqsortを使ってポインタの2次元配列をソートしようとしています。私が今持っている唯一の問題は、もともと私は静的に宣言された配列をポインタに切り替えることを使用していたことです。私は構造体に切り替えることにほとんど誘惑されていますが、これを動作させることができないということは頑固です。2次元のポインタ配列を並べ替える

これまでのところ、私はポインタの2D配列ををmalloc [] [メートルをarray2d [3]した所期のサイズ]:

 int **array2d; 

    array2d = (int**)malloc((m)*sizeof(int*)); 

    for(i=0; i<=m; i++) 
     array2d = [i]=(int*)malloc(3*sizeof(int)); 
    qsort(array2d, m, 3*sizeof(int**),comp); 

私の比較は以下のとおりです。

int comp(const void* left, const void*right)                     
{ 

    const int *a = *(const int**)left; 
    const int *b = *(const int**)right; 

    return a-b; 
} 

私はありませんが、 2dポインタで動作するようにcompareを構造化する方法を確認してください。

+0

あなたの 'comp'関数が間違っています。 'a'が最小の整数値で、' b'が1の場合はどうでしょうか?整数演算のラップアラウンドのため、 'a-b'は(ほとんどのシステムで)可能な最大整数値になります。これは' comp'の結果が負でなければならない場合でも正です。 –

+0

3つのintは単一の大きな値ですか? (intが32ビットの場合、96ビット数) – Skizz

+0

3はもともと2次元の内側の3つのスペースを表していました.1行目のように3つの値があります。 –

答えて

1

あなたが提供したコードスニペットから、私はあなたが別々に行列の各行をソートしようとしていたと仮定しています。私が気づいた最初のことは、マトリックスの列(2番目のインデックス)のメモリ割り当てにタイプミスがあることです。

NUMROWの正しいメモリ割り当て X 次のようにnumColumnsの行列は次のようになります。

/* loop counter */ 
int i; 

/* dynamic array sizes */ 
const int numRow = 5; 
const int numColumns = 25; 

/* allocate the row pointers */ 
int **dynamic2d = (int **)malloc(numRow * sizeof(int *)); 

/* for each row pointer */ 
for(i = 0; i < numRow; i++) 
{ 
    /* allocate columns */ 
    dynamic2d[i] = (int *)malloc(numColumns * sizeof(int)); 
} 

次はあなたが単に一度だけのqsort(..)メソッドを呼び出すことはできません。この方法では、「フラット」または1次元の配列が必要です。行列の各行に対してqsort(...)メソッドを個別に呼び出す必要があります。これは次のとおりです。

/* sort array */ 
for(i = 0; i < numRow; i++) 
    qsort(dynamic2d[i], numElements, sizeof(int *), comp); 

最後に、コンパレータ方式で間違いをしました。このメソッドには、正しく動作するために従う必要がある厳密な規則があります。 Current specifications say "アプリケーションは、最初の引数がそれぞれ2番目の引数よりも小さい、等しい、またはより大きいと見なされる場合、関数が0より小さい、等しい、またはより大きい整数を返すようにしなければならない。同じようにソートされた配列の順序は不明です。 "

これは簡単な修正です。以下単に見られるように、これらの結果を生成するためのロジックを記述します。

int comp(const void* firstArg, const void* secondArg) 
{ 
    /* get the values of the arguments */ 
    int first = *(int *)firstArg; 
    int second = *(int *)secondArg; 

    /* return the value as expected by the qsort() method */ 
    if(first < second) 
    { 
     return 1; 
    } 
    else if(second < first) 
    { 
    return -1; 
    } 

    return 0; 
} 

注目すべき最後の事、これは少なくともに最大のソートされます。 コンパレータのロジックを切替えないでください。並べ替えは正確な結果を返しません。これを行う正しい方法は、以下のように配列を先頭から前に読み込むことです。 コンパレータの引数を入れ替えてソート順序を変更したり、結果を前後に読み取ったりできます。

int comp(const void* firstArg, const void* secondArg) 
{ 
    /* get the values of the arguments */ 
    int first = *(int *)secondArg; 
    int second = *(int *)firstArg; 
    ... 
} 

または

/* print greatest to smallest */ 
for(i = 0; i < numRow; i++) 
{ 
    /* start at front and work to back */ 
    for(j = 0; j < numColumns; j++) 
     printf("%d ", dynamic2d[i][j]); 
    printf("\n"); 
} 

/* print smallest to greatest */ 
for(i = 0; i < numRow; i++) 
{ 
    /* start at back and work to front */ 
    for(j = numColumns- 1; j >= 0; j--) 
     printf("%d ", dynamic2d[i][j]); 
    printf("\n"); 
} 

うまくいけば、このことができます!行列全体をソートする必要がある場合、それはすべて一緒に別の獣です。

関連する問題