2016-11-28 65 views
0

如果我在C中有一個帶有座標x和y的結構POINT,那麼通過對的第一個元素對它進行排序的可接受方式是那麼第二個如果第一個是平等的?我在C++上發現了很多這方面的答案,但在C中沒有。你可以幫忙嗎?按第一個元素排序向量,然後按C中第二個元素排序C

+0

可能您[tag:C++]找到的內容可以與[tag:c]一起使用。順便說一句,這是一個太廣泛的問題。 – LPs

+1

只需使用'qsort'和一個適當的比較函數 - 參見[man qsort](https://linux.die.net/man/3/qsort)。 –

+0

對於C++,它使用了一些不在C和Im中的東西,而不是經驗豐富的程序員將其從C++「轉換」爲C,因此可以幫助我嗎? –

回答

-1

有幾個答案了,但其實施似乎過於複雜;)

struct pair 
{ 
    int x; 
    int y; 
}; 

static inline int safe_cmp(int x, int y) 
{ 
    return (x > y) - (x < y); 
} 

int lex_cmp_pairs(const void *left, const void *right) 
{ 
    const struct pair *l = left; 
    const struct pair *r = right; 
    const int cmp_x = safe_cmp(l->x, r->x); 
    const int cmp_y = safe_cmp(l->y, r->y); 
    return (cmp_x == 0) ? cmp_y : cmp_x; 
} 

/* example usage: */ 
struct pair ps[] = { {3, 3}, {2, 5}, {1, 1}, {2, 2}, {1, 2}, {3, 1} }; 
qsort(ps, 6, sizeof(struct pair), lex_cmp_pairs); 

請注意,如果您打算在線程環境中進行排序,您可能需要使用qsort_r(GNU擴展)。

+2

使用減法進行比較是非常糟糕的做法。試試你的函數:創建兩個結構點,將x設置爲0,設置a.y = INT_MAX,b.y = -1。現在,b比你的函數中的要大。將a.y設置爲INT_MAX - 1,它突然變小。這個比較函數是非傳遞的。此外,如果事情變得太小,通過整數下溢的未定義行爲。 – Art

+0

你說得對(發現它+1) - 通過引入安全比較來固定(但仍然沒有引入不必要的分支)。 –

+0

@PatrykObara:'qsort_r'用於將上下文傳遞給比較函數,而不使用全局變量,這對於線程應用程序來說更好,儘管您可以使用帶有本地存儲的全局變量。這裏沒有必要,因爲比較功能只使用入口數據。 – chqrlie

5

只需使用qsort和適當的比較功能,例如,

// point type 

typedef struct { 
    int x; 
    int y; 
} Point; 

// point compare function 

int compare_points(const void *p1, const void *p2) 
{ 
    const Point *pt1 = p1; 
    const Point *pt2 = p2; 

    // do primary compare on x 
    if (pt1->x > pt2->x) 
     return 1; 
    if (pt1->x < pt2->x) 
     return -1; 

    // pt1->x == pt2->x - do secondary compare on y... 
    if (pt1->y > pt2->y) 
     return 1; 
    if (pt1->y < pt2->y) 
     return -1; 

    // pt1 == pt2 
    return 0;   
} 

// sort an array of points... 

qsort(points, num_points, sizeof(Point), compare_points); 

LIVE DEMO

+1

謝謝,這正是我所期待的:) –

+1

沒有必要從'void *'強制轉換爲更具體的指針類型。此外,通常不建議依賴有符號整數下溢。 – unwind

+0

@unwind:演員表上的好點子 - 謝謝 - 答案已更新。我會做的比較邏輯有點更強大的不久,太... –

1

,你既可以寫一個獨特的比較功能

int comparator(POINT* p1, POINT* p2) { 
    if (p1->x < p2->x) { 
     return -1; 
    } 
    if (p1->x > p2->x) { 
     return 1; 
    } 
    if (p1->y < p2->y) { 
     return -1; 
    } 
    if (p1->y > p2->y) { 
     return 1; 
    } 
    return 0; 
} 

,並與任何正常的排序實現中使用它,

,或者你可以定義的範圍你的座標(例如0 < x < 100) 這個假設,你可以在一個整數結合了座標和使用任何基於INT-排序實現

int createCombinedCoordinate(POINT* p1) { 
    return P1->x * 100 + p1->y; 
} 
相關問題