2017-10-22 67 views
0

私は昇順でソートしようとしている2D配列を持っています。例えば、配列はこのように見えたと言う:C - 最初の次元で2次元配列をソート

4, 5 
2, 6 
7, 2 
8, 4 

私はそれは次のようになりたいと思います:

2, 6 
4, 5 
7, 2 
8, 4 

私がこれまで持っているコード:

int temp = 0; 
for(int m = 0; m<=nonZeroLength-1; m++){ 
    for(int n = m+1; n<=nonZeroLength-1; n++){ 
     if(nonZeroScoreSorcting[m] > nonZeroScoreSorcting[m+1]){ 
      temp = nonZeroScoreSorcting[m]; 
      strcpy(nonZeroScoreSorcting[m], nonZeroScoreSorcting[n]); 
      strcpy(nonZeroScoreSorcting[n], temp); 
     } 
    } 
} 

が想定をnonZeroLengthの値はこの例では4です。私はC言語で配列の要素を変更する唯一の方法であることを読んでいるので、私はstrcpy()を使用しています、私はプログラムを実行すると、私はエラーを取得(ただしthatsの場合はtrueわからない。):私が持っている

passing argument 1 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]

をまた、定期的な割り当て方法を試してみました:

if(nonZeroScoreSorcting[m] > nonZeroScoreSorcting[m+1]){ 
    temp = nonZeroScoreSorcting[m]; 
    nonZeroScoreSorcting[m] = nonZeroScoreSorcting[n]; 
    nonZeroScoreSorcting[n] = temp; 
} 
+1

**私はstrcpy()を使用しています。これは、Cで配列の要素を変更する唯一の方法です。(確かに正しいかどうかわかりません)** 'まったく間違っています。 'nonZeroScoreSorcting'の定義は何ですか? 2D配列だと言っていますが、1D配列のように使用しています。 – MFisherKDX

+2

私たちのお手伝いをするには、[**最小、完全、かつ確認可能な例**](http://stackoverflow.com/help/mcve)を投稿する必要があります。さもなければ、私たちはあなたのコードの他の領域で何が起こるかを推測しておき、ここでの答えに影響を与えます。あなたの配列は本当に 'int'の2次元配列で、' strcpy'は間違っています。 –

+0

@David私のコードの他のセクションは問題ありません。私が含まなかった唯一のものは、2D配列の減速でした。私の質問では、例の内容を提供しました。 –

答えて

1

あなたは、行で配列をソートするための鍵は、ソート時に、あなたはを交換する必要があることを理解していることを示すようintの2次元配列を持って実際に行う場合行、単に値ではありません。これは、並べ替えの間に行ごとの関係を保持する方法です。

あなたは文字列としてintの各行を処理し、strcpyを使用して行単位のコピーを試みることはできません。これにより、未定義の動作strcpyが、配列境界外のsrc引数の値にアクセスして、ヌル終了の文字が存在しない場合にアクセスします。

(ただし、技術的に、各srcdestため適切なサイズのアレイを提供しないNUL終端文字がない場合n文字に読み取り制限によって行をコピーすることができ2 * sizeof(int)バイトをコピーするstrncpy'n'サイジングそれは何ですか?memcpy(またはmemmove)が対象です。

stdlib.hで提供されているqsort関数を使用してCで並べ替えることをお勧めしますが、必要な並べ替えアルゴリズムを指定できます。それはqsortの効率に近くない可能性が高く、確かに徹底的にテストされた近くにはありません。

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

int main (void) { 

    int a[][2] = {{ 4, 5 }, 
        { 2, 6 }, 
        { 7, 2 }, 
        { 8, 4 }}, 
     n = sizeof a/sizeof *a, 
     col = sizeof *a/sizeof **a; 

    for (int i = 0; i < n; i++) /* insertion sort of a by row */ 
     for (int j = i; j > 0 && *a[j] < *a[j-1]; j--) { 
      int tmp[col]; /* temporary VLA */ 
      memcpy (tmp, a[j], sizeof *a); 
      memcpy (a[j], a[j-1], sizeof *a); 
      memcpy (a[j-1], tmp, sizeof *a); 
     } 

    for (int (*p)[2] = a; p < a + n; p++) /* output results */ 
     printf ("%d, %d\n", (*p)[0], (*p)[1]); 

    return 0; 
} 

使用例/出力

$ ./bin/inssort2d 
2, 6 
4, 5 
7, 2 
8, 4 

を記述することにより困惑しているqsort最も新しいCプログラマでは次のようにシンプルな行ソート遅い古い挿入ソートを使用しては行うことができますは、の機能をqsortに渡して、その仕事をさせる機能です。本当にそれほど難しいことではありません。 qsortは、あなたが比較関数の引数としてソートしているものの2つにポインタを渡すことを知っています。

この場合、各行の最初の要素に基づいて整数の行(1Dの整数の配列)をソートします。したがって、qsortは2つのint *(intへのポインタ)を比較します。各配列の最初の要素だけが気になります(ポインタの逆参照によって簡単に取得できます)。単純なことができ、ここで比較:

int cmp (const void *a, const void *b) 
{ 
    /* (a > b) - (a < b) */ 
    return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); 
} 

(注:2つの不等式の結果を使用することによって、あなたは単に一人で減算の結果を返した場合に発生する可能性がオーバー/アンダーフローに対する保護)。

完全qsort実装は次のようになります(出力は同じです)

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

int cmp (const void *a, const void *b) 
{ 
    /* (a > b) - (a < b) */ 
    return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); 
} 

int main (void) { 

    int a[][2] = {{ 4, 5 }, 
        { 2, 6 }, 
        { 7, 2 }, 
        { 8, 4 }}, 
     n = sizeof a/sizeof *a; 

    qsort (a, n, sizeof *a, cmp); /* qsort array of pointers */ 

    for (int (*p)[2] = a; p < a + n; p++) /* output results */ 
     printf ("%d, %d\n", (*p)[0], (*p)[1]); 

    return 0; 
} 

両方の方法に比べて

ルックとqsortが好ましい方法であるが、学習のために、何も問題がないことを知っています手でそれをやって経験を得る。さらに質問がある場合はお知らせください。