我正在尝试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);
}
}
这不能正常工作。
提前致谢。
答案 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)
这应该是你要找的。 p>
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
现在来到最后一个条件。如果pp
为simpson bart 25
且qq
为simpson 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;
}
}
}