c中的qsort多条件排序条件

  • 本文关键字:条件 排序 qsort 中的 c
  • 更新时间 :
  • 英文 :


上下文:字符串数组用函数比较器对C和qsort进行排序不同的

编译器资源管理器上的完整代码。

char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
{"America", "Cycling", "Mens", "Gold"},
{"New Zealand", "Swimming", "Womens", "Silver"},
{"India", "Badminton", "Mens", "Bronze"}};
qsort(str,ROWS,sizeof(*str),(compare_rows));
static int compare_rows(const void * a,
const void * b) {
const int sort_colmn = 0;
char * x1 = ((char ** ) a)[sort_colmn];
char * x2 = ((char ** ) b)[sort_colmn];
if (x2 == "India") return 1;
if (x1 > x2 && x2 != "India") return 1;
else if (x1 == x2) return 0;
else return -1;
}

我正在尝试复制以下SQL排序:

select * from (values('Russia'),('America'),('New Zealand'),('India')) cte(a) 
order by a='India' desc, a asc;

所需订单:

+-------------+
|      a      |
+-------------+
| India       |
| America     |
| New Zealand |
| Russia      |
+-------------+

compare_rows函数中,您试图通过比较字符串的地址来比较字符串。你不能那样做。

例如,比较x2 == "India"不太可能为真,除非x2指向该比较的RHS上字符串文字的"合并"值。其他指针比较也存在类似的条件。

要比较给定char*操作数指向的字符串,需要调用strcmp函数:

static int compare_rows(const void* a, const void* b)
{
const int sort_colmn = 0;
// Note the added use of `const` for the pointers and casts ...
const char* x1 = ((char*const*)a)[sort_colmn];
const char* x2 = ((char*const*)b)[sort_colmn];
if (strcmp(x1, "India") == 0) return -1; // Need to also add this test!
if (strcmp(x2, "India") == 0) return 1;
if (strcmp(x1, x2) > 0) return 1; // Comparing x2 to "India" here is redundant
else if (strcmp(x1, x2) == 0) return 0;
else return -1;
//  A much simpler way to encode the above three lines is just:
//  return strcmp(x1, x2);
}

您的2D数组str是(16(个内存地址的连续集合,每个"ptr"彼此独立。。。qsort在块中操作,无论是整数、指针还是结构。

要清楚地使用qsort,首先将4个"列"绑定到单个块中:

typedef struct {
char *nation;
char *sport;
char *gender;
char *medal;
} res_t;
res_t results[] = {
{"Russia", "Boxing", "Mens", "Gold"},
{"America", "Cycling", "Mens", "Gold"},
{"New Zealand", "Swimming", "Womens", "Silver"},
{"India", "Badminton", "Mens", "Bronze"}
};

现在,results是一个由4个结构组成的数组。现在,您可以调用qsort()

qsort( results, sizeof(results)/sizeof(results[0]), sizeof( results[0] ), compare );

sizeof( results[0] )是一个元素的大小,并且sizeof(results)/sizeof(results[0])是(编译器计算的(元素数("行"(。

您的专用比较功能可以变得更简单(更有效(。。。

static int compare( const void *a, const void *b ) {
res_t *p1 = (res_t *)a;
res_t *p2 = (res_t *)b;
char *alwaysFirst = "India";
if( strcmp( p1->nation, alwaysFirst ) == 0 ) return -1;
if( strcmp( p2->nation, alwaysFirst ) == 0 ) return  1;
return strcmp( p1->nation, p2->nation );
}

最新更新