2017-07-06 15 views
0

[i] [0]、a [i + 1] [0]について、2次元配列a [n] [2] a [i] [1]、a [i + 1] [1]を減少させる。 qsortは整数配列では正常に動作しますが、長いlong配列では動作しません。qsortがlong longで正常に動作しない

整数配列コード

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

int cmpfunc(const void* a, const void* b) 
{ 
    int x = ((int*)a)[0] - ((int*)b)[0]; 
    if (x != 0) { 
     return x; 
    } 
    return ((int*)a)[1] - ((int*)b)[1]; 
} 

int main(int argc, char const* argv[]) 
{ 
    int n, i, j; 
    scanf("%d", &n); 
    int a[n][2]; 
    for (i = 0; i < n; i = i + 1) { 
     scanf("%d %d", &a[i][0], &a[i][1]); 
    } 
    qsort(a, n, sizeof(a[0]), cmpfunc); 
    for (i = 0; i < n; i = i + 1) { 
     printf("%d %d\n", a[i][0], a[i][1]); 
    } 
    return 0; 
} 

長い長い配列コード

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

int cmpfunc(const void* a, const void* b) 
{ 
    int x = ((int*)a)[0] - ((int*)b)[0]; 
    if (x != 0) { 
     return x; 
    } 
    return ((int*)a)[1] - ((int*)b)[1]; 
} 

int main(int argc, char const* argv[]) 
{ 
    int n, i, j; 
    scanf("%d", &n); 
    long long a[n][2]; 
    for (i = 0; i < n; i = i + 1) { 
     scanf("%I64d %I64d", &a[i][0], &a[i][1]); 
    } 
    qsort(a, n, sizeof(a[0]), cmpfunc); 
    for (i = 0; i < n; i = i + 1) { 
     printf("%I64d %I64d\n", a[i][0], a[i][1]); 
    } 
    return 0; 
} 

入力:最初のコードの

5 
4 3 
4 2 
4 1 
4 1 
4 1 

出力:

第二のコードのための

出力:

4 2 
4 1 
4 1 
4 1 
4 3 
+2

を、あなたが何かを忘れていませんか?特に比較機能では? 'a'と' b'の実際のタイプは何ですか? –

+0

コードのデバッグ方法を学ぶことをお勧めします。まず、変数の値を表示するために 'printf()'ステートメントを追加します。 –

+0

@Someprogrammerdudeどのように重要ですか?入力はまだint型の範囲ですが、int型でも正しく動作しますか? – Vishal

答えて

1

は、あなたが実際に問題があります:最初は無効なキャストを有するものです。 2番目はでもで、無効なキャスティングについてですが、もう1つ理由があります。

私のコメントの1つに述べたように、qsort関数は、ポインタを比較関数に渡します。配列arrがある場合、qsortは引数として&arr[0]のようなものを使用します。つまり、配列のデータ自体が配列の場合、引数は配列へのポインタになります。あなたの特定のケースでは、引数型は実際にlong long (*)[2]で、long long *だけではありません。

だから、比較関数は、代わりに次のようになります。あなたが `長いlong`を使用する場合は

int cmpfunc(const void* a_, const void* b_) 
{ 
    long long (*a)[2] = (long long (*)[2]) a_; 
    long long (*b)[2] = (long long (*)[2]) b_; 

    long long result; 

    if ((*a)[0] - (*b)[0] != 0) 
     result = (*a)[0] - (*b)[0]; 
    else 
     result = (*a)[1] - (*b)[1]; 

    if (result < 0) 
     return -1; 
    else if (result > 0) 
     return 1; 
    else 
     return 0; 
} 
+0

const指定子を保持することは可能ですか?うん、ちょうど 'long long const(* a)[2] = a_;'をキャストする必要はありません。 – Stargateur

+0

2つの 'long long int 'の違いの結果は' int'の範囲にはありませんでしたので、このqsortの実装は使用できません。これは間違っていますか?また、あなたのコードはこの質問に対して適切に動作していないので、実際の問題は 'scanf'プレースホルダにあるので試してみてください。 – BetaRunner

+0

@BetaRunner一般的なケースでは、差が大きくなる可能性があります。減算の結果を変数に格納し、それを使って 'int'を返すように更新されました。 –

1

は、あなたはまだあなたがlong longにデータの種類を変更していても、あなたの比較関数でint *にキャスト。

+0

どのように重要ですか?入力はまだint範囲です。 – Vishal

+0

@Vishal 'sizeof(long long)!= sizeof(int)'ならばどうしますか?これは非常に可能性が高い(long longは少なくとも64ビットであり、intは通常64ビットシステムでも32ビットである)。 –

+0

@Vishal 'long long'値を' int'にキャストしていて、その値が 'int'の範囲内にある場合、問題はありません。しかし、 'long long *'を 'int *'に変換するのは非常に異なります。ポインターを扱う場合、値の範囲は無関係です。 –

0

コンパイル時に警告を有効にした場合(-Wall -pedantic gccの場合)、long long intに別のプレースホルダーが必要であり、それが64-bitであるとは見なすことができません。また、compare関数の引数を誤ってキャストします。 2つのlong long intの違いがintの範囲外になる可能性があるので、それを使用することはできません(私が書いたもの)qsort()の実装を比較してください。ここでは、コードです:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <math.h> 
#include <limits.h> 
int cmpfunc(const void *a,const void *b){ 
    long long int x=((long long int *)a)[0]-((long long int *)b)[0]; 
    if(x!=0){ 
     return x; 
    } 
    return ((long long int *)a)[1]-((long long int *)b)[1]; 
    } 


int main(int argc, char const *argv[]){ 
    int n,i; 
    scanf("%d",&n); 
    long long a[n][2]; 
    for(i=0;i<n;i=i+1){ 
     scanf("%lld %lld",&a[i][0],&a[i][1]); 
    } 
    qsort(a,n,sizeof(a[0]),cmpfunc); 
    for(i=0;i<n;i=i+1){ 
     printf("%lld %lld\n",a[i][0],a[i][1]); 
    } 
    return 0; 
} 
関連する問題