【问题标题】:Double comparing by qsort in C在C中通过qsort进行双重比较
【发布时间】:2020-07-19 11:10:11
【问题描述】:

我能问一下双重排序是如何工作的吗?

我只想按票数比较两个人(例如 10 JAMES 和 8 Jack)应该看起来像 10 詹姆斯 8 杰克

我使用 qsort 使这成为可能,但如果我想按 alpha 顺序(例如 10 JAMES、8 JACK、10 ALEXA)对具有相同票数的人进行排序应该看起来像 10 亚历克萨 10 詹姆斯 8 杰克

我的比较函数看起来像:

int compare(const void* p1, const void* p2){
           return ( ((const struct student*) p2)->votes - ((const struct student*) p1)->votes );
           int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
           if(value==0)
           {
                return stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
           }

}

然后在那里进行 qsort

qsort ((void*) databaza, size, sizeof(struct student), compare);

但它不起作用,谁能解释为什么? 非常感谢!

【问题讨论】:

  • 您的比较函数在查看name 之前正在执行return 语句。该函数的其余部分也是错误的。为什么它减去 name 指针,然后只在指针值的差异为 0 时才比较名称?

标签: c sorting pointers struct qsort


【解决方案1】:

你来了。

int compare( const void *p1, const void *p2 )
{
    const struct student *left  = p1;
    const struct student *right = p2;

    int result = ( right->votes < left->votes ) - ( left->votes < right->votes );

    return result == 0 ? strcmp( left->name, right->name ) : result;
}

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME_SIZE   20
struct student
{
    unsigned int votes;
    char name[NAME_SIZE];
};

int compare( const void *p1, const void *p2 )
{
    const struct student *left  = p1;
    const struct student *right = p2;

    int result = ( right->votes < left->votes ) - ( left->votes < right->votes );

    return result == 0 ? strcmp( left->name, right->name ) : result;
}

int main(void) 
{
    struct student students[] =
    {
        { 10, "JAMES" },
        {  8, "JACK" }, 
        { 10,  "ALEXA" }
    };

    const size_t N = sizeof( students ) / sizeof( *students );

    qsort( students, N, sizeof( struct student ), compare );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%2u, %s\n", students[i].votes, students[i].name );
    }
    putchar( '\n' );

    return 0;
}

程序输出是

 8, JACK
10, ALEXA
10, JAMES

至于你的比较功能

int compare(const void* p1, const void* p2){
           return ( ((const struct student*) p2)->votes - ((const struct student*) p1)->votes );
           int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);
           if(value==0)
           {
                return stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);
           }

}

然后在它的开头有一个return语句。所以return语句后面的代码不会被执行。

此声明

int value = (((const struct student*)p2)->name - ((const struct student*)p1)->name);

具有未定义的行为,因为两个不指向同一数组元素的指针存在差异。

这个电话

stcrmp(((const struct student*) p1)->name - ((const struct student*) p2)->name);

没有意义,也不会编译,因为函数 strcmp 需要两个 char * 类型的参数。

【讨论】:

  • 善用int result = ( int1 &lt; int2 ) - ( int1 &lt; int1 );成语。想法:可以避免与qsort( students, N, sizeof *students, compare );的类型匹配
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 2022-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多