按数字排序2D字符数组

时间:2014-08-26 15:30:54

标签: c arrays sorting pointers

我一直在寻找解决方案,但似乎找不到与我类似的解决方案。我试图排序 某列的2D char *数组。

char *objs[50][3];

/***** within a loop to populate with values *****/
objs[count][0]=obj->level; //this is a number to be sorted
objs[count][1]=obj->cost;  //this is a number
objs[count][2]=obj->short_desc->str;  //this is a string
count++;
/***** end loop *********/

qsort(objs, count, sizeof(char *), compare_function); //to sort by obj->level, int values

我删除了我以前的解决方案,因为它显示了各种类型 奇怪的数字甚至不排序。我不是很有经验 C,非常感谢有关如何做到这一点的帮助。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

在" C"中排序隐式结构时由2d arrays定义,其中每一行对应一个对象,我发现使用qsort_s()很有用,因为它允许我传递有关要排序到比较函数中的数组条目的更多信息。

因此,以下内容接受带有nRows行和nColumns列的字符串的二维数组,并对sortColumnIndex指定的列进行排序。提供给context的额外qsort_s()指针将排序索引传递给排序方法,而不需要全局变量:

struct sort_on_index_context
{
    size_t nRows;
    size_t nColumns;
    size_t sortColumnIndex;
};

static int compare(void *p_vcontext, const void *ventry1, const void *ventry2)
{
    struct sort_on_index_context *p_context = (struct sort_on_index_context *)p_vcontext;
    char **entry1 = (char **)ventry1;
    char *s1 = entry1[p_context->sortColumnIndex];
    char **entry2 = (char **)ventry2;
    char *s2 = entry2[p_context->sortColumnIndex];

    return strcmp(s1, s2);
}

void sort_on_index(char **objs, size_t nRows, size_t nColumns, size_t sortColumnIndex)
{
    struct sort_on_index_context context;

    if (sortColumnIndex < 0 || sortColumnIndex >= nColumns)
        return; /* Print an error or throw an exception! */

    context.nColumns = nColumns;
    context.sortColumnIndex = sortColumnIndex;
    context.nRows = nRows;

    qsort_s(objs, nRows, sizeof(char *) * nColumns, compare, (void *)&context);
}

我们传递sizeof(char *) * nColumns因为我们希望qsort_s将每个连续的nColumns个char指针组视为要按顺序重新排列的单个块。

然后你会称之为:

char *objs[50][3];
size_t nRows = sizeof(objs)/sizeof(objs[0]);
size_t nColumns = sizeof(objs[0])/sizeof(objs[0][0]);
size_t column_id_to_sort = 1; /* or whatever you want to define as your sort key. */

/* Fill up your "objs" array however you like */

/* Now do the sort: */

sort_on_index(&objs[0][0], nRows, nColumns, column_id_to_sort);

修改

如果您的开发环境中没有qsort_s或某些等效项,您可能需要通过静态变量向排序函数传达必要的信息,例如

static struct sort_on_index_context context;

static int compare(const void *ventry1, const void *ventry2)
{
    char **entry1 = (char **)ventry1;
    char *s1 = entry1[context.sortColumnIndex];
    char **entry2 = (char **)ventry2;
    char *s2 = entry1[context.sortColumnIndex];

    return strcmp(s1, s2);
}

<强>更新

您可以扩展方法以提供您自己的自定义比较方法,如下所示:

struct sort_on_index_context_custom
{
    size_t nRows;
    size_t nColumns;
    size_t sortColumnIndex;
    int (*comparer)(const char *, const char *);
};

static int compare_custom(void *p_vcontext, const void *ventry1, const void *ventry2)
{
    struct sort_on_index_context_custom *p_context = (struct sort_on_index_context_custom *)p_vcontext;
    char **entry1 = (char **)ventry1;
    char *s1 = entry1[p_context->sortColumnIndex];
    char **entry2 = (char **)ventry2;
    char *s2 = entry2[p_context->sortColumnIndex];

    return p_context->comparer(s1, s2);
}

void sort_on_index_custom(char **objs, size_t nRows, size_t nColumns, size_t sortColumnIndex, int (*comparer)(const char *, const char *))
{
    struct sort_on_index_context_custom context;

    if (sortColumnIndex < 0 || sortColumnIndex >= nColumns)
        return; /* Print an error or throw an exception! */

    context.nColumns = nColumns;
    context.sortColumnIndex = sortColumnIndex;
    context.nRows = nRows;
    context.comparer = comparer;

    qsort_s(objs, nRows, sizeof(char *) * nColumns, compare_custom, (void *)&context);
}

然后像这样调用它来将给定的字符串列整数为整数:

static int integer_compare(const char *s1, const char *s2)
{
    int int1 = atoi(s1);
    int int2 = atoi(s2);
    return int1 - int2;
}

sort_on_index_custom(&objs[0][0], nRows, nColumns, 1, integer_compare);