2017-01-07 10 views
-2

2行の2D配列を持ち、非常に大きな数(10^9まで)を持っています。 0th行に基づいて配列をソートしようとしています。C++:1行に基づく2次元配列のソート

例:私は配列があります:A[5][2]={{1,0},{3,1},{2,2},{6,3},{5,4}}ここで、2行目は要素のインデックスです。

今、元のインデックスを保持して配列を並べ替える必要があります。

Aがあるべきソート後:

A[5][2]={{1,0},{2,2},{3,1},{5,4},{6,3}} 

私は次のようでした:

long long a[n+1][2]; 

    for (long long i = 0; i < n; i++) 
    { 
     cin>>a[i][0]; 
     a[i][1]=i; 
    } 



    qsort(a, n, sizeof a[0], compare); 

と機能を比較している:それは数字の小さい値のために働いている

int compare (const void *pa,const void *pb) 
{ 
    int *a = (int*)pa; 
    int *b = (int*)pb; 
    if(a[0] == b[0]) 
     return a[1] - b[1]; 
    else 
     return a[0] - b[0]; 
} 

。大きな値の場合は、実行時エラー(SIGSEGV)が発生します。

誰かがエラーを修正するのを手助けできますか?それとももっと効率的な方法がありますか?

注::私は比較機能で長い間試してみましたが、変換エラーが発生していました。
error: invalid conversion from 'll (*)(const void*, const void*) {aka long long int (*)(const void*, const void*)}' to '__compar_fn_t {aka int (*)(const void*, const void*)}' [-fpermissive]

EDIT:実は私は、ソート後にのみインデックスを離れて仕事ができます。

+1

「long long」と「int」が混在している可能性がありますか? –

+0

forループでlong longの代わりにsize_tを使用する方が良いことに気付きたいだけです。 –

+0

変換エラーを表示します。 –

答えて

2

まず、配列が正しく宣言されていません(下のサンプルコードは正しい宣言を示しています)。

第2に、最初の行だけを残して、2番目の行のインデックスのみを並べ替えることをお勧めします。 2番目の行がインデクサとして使用されているため、最初の行をソートする必要はありません。

第3に、qsortをC++で使用することはお勧めしません。

  1. qsortはタイプセーフではありません。 で並べ替える型にvoidポインタをキャストしなければなりません。キャストが正しく行われないと、プログラムに実行時の問題が発生します。
  2. qsortは、非PODタイプ(Cに対応していないもの)では使用できません。
  3. C++コンパイラ・オプティマイザはqsortよりも速度が最適化されています。std::sort
  4. std::sortの方が使いやすいです。第二行はなく、1行目の

    #include <algorithm> 
    #include <iostream> 
    
    int main() 
    { 
        int A[2][5] = { {1,3,2,6,5},{0,1,2,3,4} }; 
    
        // sort the index row, not the "data" row 
        std::sort(A[1], A[1] + 5, 
           [&](int n1, int n2){ return A[0][n1] < A[0][n2]; }); 
    
        // output results 
        for (int i = 0; i < 2; ++i) 
        { 
         for (int j = 0; j < 5; ++j) 
         { 
          if (i == 0) // if this is a data row 
           std::cout << A[i][A[1][j]] << " "; 
          else // this is an index row 
           std::cout << A[i][j] << " "; 
         } 
         std::cout << "\n"; 
        } 
    } 
    

    Live Example

    std::sort作品:ここ

は実施例です。比較ラムダは、第1行のデータに基づいて第2行をソートする。

出力ループは、2番目の行が指定されている場合、最初の行のインデックスを作成する方法を示しています。例えば、最初の行でソート第3の数を取得する:A[1][2]ので

A[0][A[1][2]]

は、第三のソート数のインデックスであり、第三のソート数はA[0][A[1][2]]

編集:

動的二次元配列を使用しようとしている場合は、std::vectorthis example shows

+0

http://ideone.com/8c7w1K:私はユーザー主導の入力でそれを試しました。比較機能にコンパイルエラーがあります。 – Buckster

+0

'long long int a [2] [n + 1];' - これは無効なC++です。変数を使用して配列のサイズを定義することはできません。実際のC++ではない 'std :: sort'を提供しています。そのため、エラーに「N3639」が記述されています。 C++の動的配列は 'std :: vector'を使って行われます。 – PaulMcKenzie

+0

@Buckster私の編集とベクターを使ったコードへのリンクをご覧ください。 – PaulMcKenzie

-1

として使用してください2つのフィールドを持つ構造体またはクラスを使用する必要があります:インデックスと数値、オーバーロード<、< =、==、>、> =演算子とオブジェクトの配列を使用し、単にソートメソッドを使用します。

関連する問題