C - Qsort:按升序对名称进行排序,按降序对等级进行排序

时间:2013-11-28 04:16:33

标签: c sorting typedef strcmp qsort

我正在尝试qsort我的记录,以便它按名称按升序对记录进行排序。如果名称具有相同名称,则会按降序对其成绩进行排序

例如:原始文本文件

simpson bart 25
simpson bart 35
simpson lisa 90
simpson bart 34

期望的输出:

simpson bart 35
simpson bart 34
simpson bart 25
simpson lisa 90

这就是我所拥有的:

int sort_nameasc_gradedes(const void *p, const void *q)
{
    const record *pp = p;
    const record *qq = q;

    int n1 = strcmp(pp->name.first, qq->name.first);
    int n2 = strcmp(pp->name.last, qq->name.last);

    if (n2 == 0 && n1 != 0) {
        return n1;
    } else if (n2 != 0  && n1 == 0) {
        return n2;
    } else {
        return (pp->score - qq->score);
    }
}

这不能正常工作。

提前致谢。

3 个答案:

答案 0 :(得分:2)

您只需要一次检查一个字段,并在一对字段不相等时立即返回。首先比较name.last并保留strcmp结果;如果它不为零,则返回它,否则进入下一个字段。然后,以相同的方式比较name.first ...如果strcmp结果不为零则返回。最后,比较score

如果score已签名并且不会接近所使用的数据类型的极值,则可以像使用减法一样使用减法,但如果无符号或减法可以包裹你需要一种不同的测试。

以下内容可能有效:

int sort_nameasc_gradedes(const void *p, const void *q)
{
    const record *pp = p;
    const record *qq = q;
    int r;

    if ((r = strcmp(pp->name.last, qq->name.last)) != 0)
        return r;
    if ((r = strcmp(pp->name.first, qq->name.first)) != 0)
        return r;
    /* return pp->score - qq->score; */
    return (pp->score < qq->score) ? 1 : ((pp->score > qq->score) ? -1 : 0);
}

答案 1 :(得分:1)

这应该是你要找的。

int sort_nameasc_gradedes(const void *p, const void *q)
{
    const record *pp = p;
    const record *qq = q;

    int n1 = strcmp(pp->name.first, qq->name.first);
    int n2 = strcmp(pp->name.last, qq->name.last);

    if (n1 != 0) {
        return n1;
    } else if (n2 != 0) {
        return n2;
    } else {
        return (qq->score - pp->score);
    }
}

首先想想你在第一和第二个条件下做了什么。你写道:

if (n2 == 0 && n1 != 0) {
        return n1;
}

如果输入是:

simpson bart 25
taufique hussain 30

对此输入的决定应基于名字,但在您的代码中,它将在最后else条件下决定并且它将产生输出

taufique hussain 30
simpson bart 25

而不是

simpson bart 25
taufique hussain 30

现在来到最后一个条件。如果ppsimpson bart 25qqsimpson bart 30,则pp->score - qq->score的值是多少? -5对吗?然后在排序数组中将是答案:

simpson bart 25
simpson bart 30

而不是你想要的:

simpson bart 30
simpson bart 25

答案 2 :(得分:1)

你想要更像这样的东西:

int sort_nameasc_gradedes(const void *p, const void *q)
{
    const record *pp = p;
    const record *qq = q;

    int n2 = strcmp(pp->name.last, qq->name.last);

    if (n2 != 0)
    {
        return n2;
    }
    else
    {
        int n1 = strcmp(pp->name.first, qq->name.first);

        if (n1 != 0)
        {
            return n1;
        }
        else
        {
            return qq->score - pp->score;
        }
    }
}