我有一个结构,并希望使用合并排序对结构数组进行排序。 我需要将排序参数传递给merge函数并访问struct成员。 这可以用C吗?
完成示例:
struct movie_imdb_data {
char color[15];
char director_name[100];
int num_critic_for_reviews;
int duration; /// in min not date and time
int director_facebook_likes;
int actor_3_facebook_likes;
char actor_2_name[100];
int actor_1_facebook_likes;
int gross;
};
在main
函数中,我有:
if (argc > 2) {
column_sort = argv[2];
}
现在我想致电merge_sort(<array of struct>, <column_sort *>)
我可以像array[0]->column_sort
那样访问数组中的成员进行比较吗?
现在我想调用merge sort并传递
我想传递数组和排序参数(我需要排序的数组)我可以使用变量代替成员名称,即..
arr[1].column_sort
而不是
arr[1].color
答案 0 :(得分:3)
听起来你想要一个命令行参数,指定要排序的字段的名称,然后对该字段进行排序。
为此,请尝试以下代码:
#include <stdlib.h>
#include <string.h>
/* compare function for field 3: "num_critic_for_reviews" */
int compField3(const void *a, const void *b)
{
struct movie_imdb_data* aStruct = (struct movie_imdb_data*)a;
struct movie_imdb_data* bStruct = (struct movie_imdb_data*)b;
return (aStruct->num_critic_for_reviews < bStruct->num_critic_for_reviews)?
-1: (aStruct->num_critic_for_reviews > bStruct->num_critic_for_reviews)?
+1: 0;
}
/* also define other compare functions for each field */
int main()
{
const char* columnName = argv[2];
struct movie_imdb_data* parray;
parray = your-array;
int (*comp)(const void *, const void *, void *) = 0;
/* map the column name to compare function for that column */
if (strcmp(columnName, "num_critic_for_reviews") == 0)
{
comp = compField3;
}
/* map other names to compare function for column */
else if (...) {...}
else { exit(1); /* if not recognized column name */ }
qsort(parray, numElementsOfArray, sizeof(struct movie_imdb_data), comp);
...
}
希望这有帮助!
答案 1 :(得分:0)
您的问题有不同的方法:
您可以编写单独的函数来比较特定字段的结构。在main
中,您可以通过测试字段的名称(或可能是非字段名称的通用名称)来选择适当的比较函数。然后,您可以将此比较函数传递给mergesort
(或qsort
...)。
如果所有成员具有相同的类型,则可以使用宏offsetof(type, member)
确定字段与结构开头的偏移量。没有通用的方法来计算这些偏移量,您需要编写一系列测试或使用表格。比较函数将使用强制转换来访问成员:
size_t member_offset = offsetof(struct movie_imdb_data, duration);
int comp_int_member(const void *a1, const void *a2) {
const int *p1 = (const int *)((const unsigned char*)a1 + member_offset);
const int *p2 = (const int *)((const unsigned char*)a2 + member_offset);
return (*p1 > *p2) - (*p1 < *p2);
}
后一种方法的缺点是它只能处理给定类型的字段。