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



我正在尝试对我的记录进行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);
    }
}

这不正常工作。

提前谢谢。

您只需要一次检查一个字段,并在一对字段不相等时立即返回。因此,首先比较name.last并保留strcmp的结果;如果它不为零,则返回它,否则继续下一个字段。然后,以相同的方式比较name.first。。。如果CCD_ 4结果不为零则返回。最后,对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);
}

这应该是您想要的。

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

您想要更像这样的东西:

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;
        }
    }
}

最新更新