自定义比较功能,用于对结构的多种类型的字段进行qsort

如何解决自定义比较功能,用于对结构的多种类型的字段进行qsort

我正在尝试使用qsort根据其字段对结构数组进行排序。我目前停留在如何创建qsort中使用的比较功能上。

结构定义:

TIME(3)

排序顺序(按优先顺序):

struct data{
  unsigned char feet;
  double lock;
  short stall;
  short gain;
  char show;
  char country;
  int king;
  unsigned int bunch;
  short strange;
  long int tiger;
  char win[9];
  float ramp;
  char sea;
  unsigned int test;
  short cave;
  char pound;
  float sofa;
};

这里是我尝试过的比较功能,但是我似乎无法获得正确的结果,请根据优先级对所有字段进行排序:

win in descending order. -
stall in ascending order. -
sea in ascending order. -
pound in ascending order. -
ramp in ascending order. -
test in descending order. -
feet in ascending order. -
show in ascending order. -
sofa in descending order. -
cave in ascending order. -
king in ascending order. -
gain in descending order. -
strange in ascending order. -
country in descending order. -
lock in descending order. -
bunch in ascending order. 
tiger in ascending order. 

解决方法

首先,您将所有else if位都变得过于复杂:

int cmpStructs(const void *a1,const void *a2){
    struct data *a = (struct data *)a1;
    struct data *b = (struct data *)a2;

    // win,descending.
    if (strcmp(a->win,b->win) > 0) return -1;
    if (strcmp(a->win,b->win) < 0) return  1;

    // stall,ascending.
    if (a->stall > b->stall) return 1;
    if (a->stall < b->stall) return -1;

    // And so on,for each field.

    return 0;
};

这样,您可以轻松注释掉比较“套房”的大块内容,从而依次测试每个字段。


您还可以考虑使用宏元编程来使它更容易和更具可读性,并且由于在复杂度内将复杂度定位在宏中,因此不易出错,例如(未经测试,但您应该了解一下) :

#define CMP_STR_ASC(s1,s2) \
    if (strcmp(s1,s2) > 0) return -1; \
    if (strcmp(s1,s2) < 0) return  1;
#define CMP_STR_DESC(s1,s2) CMP_STR_ASC(s2,s1)

#define CMP_VAL_ASC(v1,v2) \
    if (v1 > v2) return -1; \
    if (v1 < v2) return 1;
#define CMP_VAL_DESC(v1,v2) CMP_VAL_ASC(v2,v1)

int cmpStructs(const void *a1,const void *a2){
    struct data *a = (struct data *)a1;
    struct data *b = (struct data *)a2;

    // Very simple rule set,based on the macros.

    CMP_STR_DESC ( a->win,b->win     )
    CMP_VAL_ASC  ( a->stall,b->stall   )
    CMP_VAL_ASC  ( a->sea,b->sea     )
    CMP_VAL_ASC  ( a->pound,b->pound   )
    CMP_VAL_ASC  ( a->ramp,b->ramp    )
    CMP_VAL_DESC ( a->test,b->test    )
    CMP_VAL_ASC  ( a->feet,b->feet    )
    CMP_VAL_ASC  ( a->show,b->show    )
    CMP_VAL_DESC ( a->sofa,b->sofa    )
    CMP_VAL_ASC  ( a->cave,b->cave    )
    CMP_VAL_ASC  ( a->king,b->king    )
    CMP_VAL_DESC ( a->gain,b->gain    )
    CMP_VAL_ASC  ( a->strange,b->strange )
    CMP_VAL_DESC ( a->country,b->country )
    CMP_VAL_DESC ( a->lock,b->lock    )
    CMP_VAL_ASC  ( a->bunch,b->bunch   )
    CMP_VAL_ASC  ( a->tiger,b->tiger   )

    return 0;
};

假设您没有做任何愚蠢的事情,例如将这些宏包装在if/while语句中而没有花括号,或者传递带有副作用的参数,它们应该保持原样(类似函数的宏通常需要保护,如果您愿意的话)可以在任何地方使用它们,但是,如果您只是将它们用作“独立”语句,则可以摆脱更简单的约束。)


实际上,正是这种对宏的复杂性的隔离使得可以轻松地解决问题,例如DevSolar在评论中提出的问题(两次运行strcmp效率不高)。

由于隔离,您只需将宏更改为以下内容即可轻松解决该问题:

#define CMP_STR_ASC(s1,s2) { \
    int cmpVal = strcmp(s1,s2); \
    if (cmpVal > 0) return -1; \
    if (cmpVal < 0) return  1; \
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res