2016-06-25 2 views
1

で新しい機能を取得するための単一の引数をC関数を提供します 1は私がセンターにその角度に基づいてリストのポイントを並べ替えしようとしています少ない引数

私はサークルにどこ気にしませんリストは開始されますが、循環的にソートする必要があります。私は、qソートを使用したいが、私の比較関数は、3(中央と比較する二つの点)がある一方で、それは、唯一の2つの引数との比較機能を必要とします。

int compareByAngle(Point *center, Point *lhs, Point *rhs) 
{ 
    return (lhs->x - center->x) * (rhs->y - center->y) - (rhs->x - center->x) * (lhs->y - center->y); 
} 

あなたは私が持つ機能を得ることができる方法を知っていますがセンターを別の関数にあらかじめ供給することによって、2つの引数だけが得られますか?これは、haskellのような言語では微風ですが、私は関数ポインタと引数を使わなければならないことは知っていますが、C言語ではどうやって行うのかわかりませんが、これらの手法にはあまり慣れていません。

ありがとうございます!

int compareByAngle(Point *lhs, Point *rhs) 
{ 
    static Point *center=NULL; 
    if (lhs==NULL) { 
     center=rhs; 
     return rhs!=NULL; // or any other usefull code 
    } else if (center==NULL) { 
     // do some error handling 
    } else { 
     return (lhs->x - center->x) * (rhs->y - center->y) - (rhs->x - center->x) * (lhs->y - center->y); 
    } 
} 

そして、それを使用する:それはポインタLHSとRHSはLHSがNULLの場合、NULL→はRHSを使用して初期化ローカル静的変数センターを使用することはできませんと仮定成し遂げるために

+1

ソートに独自のカスタム関数を使用してみませんか? – wrangler

+2

'qsort'比較関数は2つの引数をとります。あなたの場合、これらは実際のデータではありませんが、 'struct'へのポインタであり、*考慮すべき3項目の情報を保持しています。 'compare'関数が0以外の値を返した場合、' qsort'はその情報を使って渡される構造体の配列をソートします。 –

+0

@wranglerこれは標準ライブラリの一部を書き直すことを意味します。ここでは不要と思われます。 – Toctave

答えて

1

一つの迅速かつ汚い方法:

#define DEFINE_CENTER NULL 
... 
// first call with NULL as lhs argument and center point as rhs argument 
if (compareByAngle(DEFINE_CENTER, center)) 
    // then use the compare function 
    qsort(base, nbmem, size, compareByAngle); 
... 

などのマクロを定義:

#define SET_COMP_CENTER(p) compareByAngle(NULL,p) 

if (SET_COMP_CENTER(center)) 
    qsort(....); 

このソリューションは、グローバルVを使用して回避ariable。

2

比較機能に構成データを渡すことはできません。これは世代のC標準化者が取り組まなかったqsortのよく知られた欠点です。

非標準関数qsort_rがあり、それは追加の引数をとり、それを3引数比較関数に渡します。残念ながら、それはどこでも利用可能ではなく、使用可能な場合、引数の順序は標準ではありません。

あなたのデータ構造を再加工することなく、これを行うための唯一のポータブルな方法は、グローバルまたは静的変数を使用することです:

static Point globalCenter; 
int compare (void* p1, void* p2) { 
    return compareByAngle(&globalCenter, p1, p2); 
} 
void myFunc() { 
    ... 
    globalCenter = center; 
    qsort(points, nPoints, sizeof(Point*), compare); 
    ... 
} 

あなたのデータ構造を手直しするために、おそらく両方のより効率的で、より明確です。どのように角度の配列を計算し、それをソートするのですか?その後、同じ順序でポイントを並べ替えます。

+0

多分それほど悪くはありません。便利な関数の中で、 'globalCenter'の設定と' qsort() 'の呼び出しを隠すことができます。関数の直前に 'globalCenter'を宣言すると、その使用を通知します(代わりに' CMP_CENTERPOINT'のようなグローバル変数を呼び出します)。 – Kusalananda

関連する問題