如果我在C中有一個帶有座標x和y的結構POINT,那麼通過對的第一個元素對它進行排序的可接受方式是那麼第二個如果第一個是平等的?我在C++上發現了很多這方面的答案,但在C中沒有。你可以幫忙嗎?按第一個元素排序向量,然後按C中第二個元素排序C
回答
有幾個答案了,但其實施似乎過於複雜;)
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擴展)。
使用減法進行比較是非常糟糕的做法。試試你的函數:創建兩個結構點,將x設置爲0,設置a.y = INT_MAX,b.y = -1。現在,b比你的函數中的要大。將a.y設置爲INT_MAX - 1,它突然變小。這個比較函數是非傳遞的。此外,如果事情變得太小,通過整數下溢的未定義行爲。 – Art
你說得對(發現它+1) - 通過引入安全比較來固定(但仍然沒有引入不必要的分支)。 –
@PatrykObara:'qsort_r'用於將上下文傳遞給比較函數,而不使用全局變量,這對於線程應用程序來說更好,儘管您可以使用帶有本地存儲的全局變量。這裏沒有必要,因爲比較功能只使用入口數據。 – chqrlie
只需使用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);
謝謝,這正是我所期待的:) –
沒有必要從'void *'強制轉換爲更具體的指針類型。此外,通常不建議依賴有符號整數下溢。 – unwind
@unwind:演員表上的好點子 - 謝謝 - 答案已更新。我會做的比較邏輯有點更強大的不久,太... –
,你既可以寫一個獨特的比較功能
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;
}
- 1. 需要幫助按二元素排序二維數組,然後按第一個元素排序(Java)
- 2. 按第三個元素排序Python列表,然後按第一個元素排序?
- 3. 按字母順序排序元素,然後按數字排序
- 4. 按元素列表的第二個元素對列表進行排序
- 5. 按行中的第一個元素對csv進行排序
- 6. C#集合 - 按元素排序(旋轉)
- 7. c#元素排序
- 8. 使用LINQ獲取第一個排序元素? (C#)
- 9. Scheme:按元素排序元素
- 10. 通過排序中的第一個元素排序的MySQL排序
- 11. 創建多個結構然後按元素排序
- 12. DataFrame元素按行排序
- 13. xslt按子元素排序
- 14. 在列表C++中查找第一個和第二個元素
- 15. XSLT按兩個元素排序;如果第一個重複,則使用第二個
- 16. 如何按第二個字符排序?
- 17. Python:按每個子列表的第一個元素排序列表列表
- 18. 我如何排序使用的第二個元素在PHP
- 19. 排序第二個元素的嵌套字符串列表(python)
- 20. 第一個浮動元素與第二個浮動元素
- 21. 如何按字母順序排列列表中的第一個元素?
- 22. 按數組最後一個元素排序mongodb
- 23. 如何選擇元素但排除第一個和最後一個元素
- 24. Ruby中的快速排序第一個元素是樞軸
- 25. 排序CSV只比較每行中的第一個元素
- 26. 排序第一個數組中的元素
- 27. 如何從排序列表中獲取第一個元素?
- 28. 排列中第k個最大元素
- 29. 如何刪除第一個元素並使第二個元素成爲java.util.NavigableSet中的第一個元素?
- 30. 強制兩個並排塊元素中的第二個填充父元素?
可能您[tag:C++]找到的內容可以與[tag:c]一起使用。順便說一句,這是一個太廣泛的問題。 – LPs
只需使用'qsort'和一個適當的比較函數 - 參見[man qsort](https://linux.die.net/man/3/qsort)。 –
對於C++,它使用了一些不在C和Im中的東西,而不是經驗豐富的程序員將其從C++「轉換」爲C,因此可以幫助我嗎? –