如何为二维数组的 qsort 编写比较器函数?

2024-01-01

我有一个 n*2 大小的数组。我想根据第二列的值使用 qsort 对它们进行排序。

#include<stdio.h>
int cmp(const int **a, const int **b) {
    //return 0;
    //return *a[1] - *b[1]
    // return *a - *b;
}
int main()
{
    int t; // test cases
    scanf("%d", &t);
    for(int i=0; i<t; i++)  {
        int n;
        scanf("%d", &n); // size of array
        int **arr = (int **)malloc(n * sizeof(int *)); 

        for(int j =0; j< n; j++) {
            arr[j] = (int *) malloc(2*sizeof(int));
        }
        for(int j =0; j< 2; j++) {
            for(int k =0; k< n; k++) {
              scanf("%d", &arr[k][j]);
            }
        }
        for(int k =0; k< n; k++) {
            for(int j =0; j<= 1; j++) {
             printf("%d\t", arr[k][j]);
            }
            printf("\n");
        }
       // qsort(arr, n, sizeof(arr[0]), cmp);
    }
    return 0;
}

所以对于输入来说,

1 2 
3 6 
0 8 
5 4 
8 9 
5 7

输出是,

1 2
5 4
3 6
5 7
0 8
8 9

我尝试过,但无法根据第二列对它们进行排序。我对将数组元素传递给比较器感到困惑。还用什么作为元素的大小传递?但我想下面的前两个是正确的。

qsort(arr, n, sizeof(arr[0]), cmp);
//qsort(arr, n, sizeof((int *)), cmp);
//qsort(arr, n, 2 * sizeof((int)), cmp);

我尝试了比较器的各种组合。

请指出方法或解释。


比较函数的原型在原型中指定qsort功能:

void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

您的比较函数必须兼容,因此您可以这样定义它:

int cmp(const void *a, const void *b) {
    /* a and b are pointers to the array of pointers. */
    int *aa = *(int * const *)a;
    int *bb = *(int * const *)b;
    return (aa[1] > bb[1]) - (aa[1] < bb[1]);
}

或者没有强制转换:

int cmp(const void *a, const void *b) {
    /* a and b are pointers to the array of pointers. */
    int * const *aa = a;
    int * const *bb = b;
    int ia = (*aa)[1];
    int ib = (*bb)[1];
    return (ia > ib) - (ia < ib);
}

请注意,您不能使用简单的比较aa[1] - bb[1]因为它可能会溢出较大的值,并且最多会产生不正确的输出。

此外,您输入的循环不正确:您应该以相反的顺序嵌套循环:

    for (int k = 0; k < n; k++) {
        for (int j = 0; j < 2; j++) {
           scanf("%d", &arr[k][j]);
        }
    }

这是修改后的版本:

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

int cmp(const void *a, const void *b) {
    /* a and b are pointers to the array of pointers. */
    int * const *aa = a;
    int * const *bb = b;
    int ia = (*aa)[1];
    int ib = (*bb)[1];
    return (ia > ib) - (ia < ib);
}

int main() {
    int t; // test cases
    scanf("%d", &t);
    for (int i = 0; i < t; i++) {
        int n;
        scanf("%d", &n); // size of array
        int **arr = malloc(sizeof(*arr) * n);

        for (int j = 0; j < n; j++) {
            arr[j] = malloc(sizeof(*arr[j]) * 2);
        }
        for (int k = 0; k < n; k++) {
            for (int j = 0; j < 2; j++) {
                scanf("%d", &arr[k][j]);
            }
        }
        qsort(arr, n, sizeof(arr[0]), cmp);
        for (int k = 0; k < n; k++) {
            for(int j = 0; j < 2; j++) {
                printf("%d\t", arr[k][j]);
            }
            printf("\n");
        }
        for (int j = 0; j < n; j++) {
            free(arr[j]);
        }
        free(arr);
    }
    return 0;
}

您还可以使用实际的二维数组来简化代码:

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

int cmp(const void *a, const void *b) {
    const int *aa = a;
    const int *bb = b;
    return (aa[1] > bb[1]) - (aa[1] < bb[1]);
}

int main() {
    int t; // test cases
    scanf("%d", &t);
    for (int i = 0; i < t; i++) {
        int n;
        scanf("%d", &n); // size of array
        int (*arr)[2] = malloc(sizeof(*arr) * n);

        for (int k = 0; k < n; k++) {
            scanf("%d%d", &arr[k][0], &arr[k][1]);
        }
        qsort(arr, n, sizeof(arr[0]), cmp);
        for (int k = 0; k < n; k++) {
            printf("%d\t%d\n", arr[k][0], arr[k][1]);
        }
        free(arr);
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为二维数组的 qsort 编写比较器函数? 的相关文章

随机推荐

  • log4j自定义jdbc附加器,数据源

    为了在我的 log4j 附加程序中使用数据源 我编写了一个自定义附加程序 附加程序尝试以 spring bean 的形式获取数据源 但是 appender 无法获取 bean 我使用的技术栈是 mybatis tomcat spring 我
  • 桌面应用程序 + Microsoft 身份验证错误

    我对桌面应用程序开发的了解有限 并且我在混合平台中开发了一个应用程序 并且在从桌面应用程序进行 Microsoft 身份验证 Azure ad 期间遇到此错误消息 仅当您从信任的商店或网站下载应用程序时才可以继续 如果需要从 Azure 应
  • Antlrworks - 无关输入

    我是这方面的新手 因此我需要你的帮助 我正在尝试解析 Wikipedia Dump 我的第一步是将它们定义的每个规则映射到 ANTLR 不幸的是我遇到了第一个障碍 第 1 行 8 外部输入 需要 我不明白发生了什么事 请帮助我 My cod
  • xterm 退出后在终端中保留 less 页面

    我经常使用 less 查看文件 并且想记住我刚刚在文件中看到的内容 但是 当我通过按 q 键退出 less 时 我的 xterm 窗口会删除显示文件的 less 页面 而只显示我的命令提示符 当我退出时 如何在终端上保留较少的输出 less
  • 手动 DAL 和 BLL 与 ORM

    哪种方法更好 1 使用一个第三方ORM系统或2 手动编写DAL和BLL代码使用数据库 1 在我们的一个项目中 我们决定使用 DevExpress XPO ORM 系统 但我们遇到了很多小问题 浪费了我们很多时间 AMD仍然时不时地遇到来自这
  • 阻止 ConstraintLayout 中的视图重叠

    我正在尝试使用 ConstraintLayout 构建一个具有三个视图的简单布局 当左视图中的文本很长时 我想看到这个 但我得到的是这样的 左视图向右增长太多并隐藏了中间视图 这是我的代码
  • 通过货物安装板条箱时出错:指定的包没有二进制文件

    我正在尝试使用 Cargo 在我的系统 Arch Linux 上安装 Rust 箱子 我可以搜索板条箱并找到我需要的东西 例如 cargo search curl head n3 Updating registry https github
  • 在公共功能分支中使用 git rebase

    您可以在网上看到人们建议不要使用git rebase在公共分支中 但如果您总是对功能分支进行变基 我看不出问题是什么 我的团队总是使用分支来实现功能 哇 我们习惯于在本地拥有它 所以变基不是问题 但有时我们想向其他开发人员展示部分完成的功能
  • 在nodeJs中,有没有一种方法可以在不使用数组大小​​的情况下循环数组?

    假设我有 myArray item1 item2 I tried for var item in myArray console log item 它打印 0 1 我所希望的是拥有 项目1 项目2 是否有任何其他语法可以在不使用的情况下工作
  • 如何在php中获取选定表项的id

    我应该得到id从表中提出请求 但我就是这样做的 我的桌子 id AI 名称 Varchar authir varchar 类别 varchar 我想如果有任何解决方案可以解决这个问题 谢谢我的问题出现在以下几行中 Print td a hr
  • Java Collection 的多个索引 - 最基本的解决方案?

    我正在寻找在 Java 集合上创建多个索引的最基本的解决方案 所需功能 当删除某个值时 与该值关联的所有索引条目都必须删除 索引查找必须比线性搜索更快 至少与 TreeMap 一样快 附带条件 不依赖于大型 如 Lucene 库 没有不常见
  • JSDOM:无法解析 CSS 样式表

    使用以下命令 node modules babel core register js node modules jsdom global register js spec jsx 我正在运行以下测试文件 use strict import
  • 导入后完整日历样式不正确

    我正在尝试在我的项目中使用 React Full Calendar 尽管日历以正确的方式呈现 但样式有点不对劲 目前的情况如下 正如您所看到的 在标题工具栏中 月份单词没有在中间对齐 其他单词和图标也是如此 也许 按钮本身的尺寸在高度上看起
  • 如何使用/安装 python 2to3?

    由此https docs python org 3 4 library 2to3 html https docs python org 3 4 library 2to3 html它说 2to3 应该作为脚本与 python 解释器一起安装
  • 如何告诉 RandomizedSearchCV 选择分布或 None 值?

    假设我们正在努力寻找最好的max depth的参数RandomForestClassifier http scikit learn org stable modules generated sklearn ensemble RandomFo
  • ddply 按 R 中的组求和

    我有一个示例数据框 数据 如下所示 X Y Month Year income 2281205 228120 3 2011 1000 2281212 228121 9 2010 1100 2281213 228121 12 2010 900
  • std::setw 和 unicode 字符

    我的问题如以下最小示例所示 include
  • 如何向此 CSS“切换器”“切换开关”添加文本

    这是实际的 Switcher 生成器 https proto io freebies onoff https proto io freebies onoff 我不清楚如何向事件添加文本 因此 当开关处于默认状态时 会显示某些文本 反之亦然
  • Mathematica 绘图中多个函数的检测和样式设置

    This https stackoverflow com questions 5597566 这个问题让我开始思考 Mathematica 如何检测正在绘制的多个函数 我发现我实在是看不懂这个流程 考虑 Plot 1 Sequence 2
  • 如何为二维数组的 qsort 编写比较器函数?

    我有一个 n 2 大小的数组 我想根据第二列的值使用 qsort 对它们进行排序 include