【问题标题】:Using qsort to sort a 2 dimensional array by columns from least to greatest使用 qsort 按列从最小到最大对二维数组进行排序
【发布时间】:2021-08-12 05:15:41
【问题描述】:

我正在尝试使用qsort 将每一列从最小到最大排序。作为一个输入的例子

 168.12.110.25
 64.113.134.35
 217.158.91.183
 102.130.129.146
 215.116.26.223
 81.162.78.0
 19.204.25.222
 245.124.138.157
 137.249.183.201
 106.61.236.67
 106.71.236.60
 106.81.240.63
 168.14.111.27
 168.17.111.27
 215.116.26.220
 137.249.111.202
 137.246.111.202

我想要一个类似于

的输出
19.204.25.222
64.113.134.35
.
.
.

106.61.236.67
106.71.236.60
.
.
.
137.246.111.202
137.246.111.202

我正在尝试使用嵌套的 for 循环遍历每一列,并告诉我一列是否大于下一列。如果代码大于 qsort 将检查并相应地移动它们。

我想知道我是否正确使用了qsort,以及我的代码是否有意义。

#include <stdio.h>
#include <stdlib.h>
 
//declare other functions/files to be used in the program
void print_fun(void);
void read_fun(void);
static int compare(const void *a, const void *b, int arg, unsigned char networks[arg][4]);
 
//read command line input and store the information
int main(int argc, char **argv) {
    //declar variable
    int arg = 0;
 
    //make argv into an int
    arg = atoi(argv[1]);
    //assign size to networks
    unsigned char networks[arg][4];
 
    //assign input to networks
    for (int j = 0; j < 1; ++j) {
        if (argc == 1) {
            printf("ERROR ERROR, you messed up\n");
        } else {
            // hold network addresses in a 2-d array, with 4 unsigned char
 
            for (int k = 0; k < arg; k++) {
                for (int i = 0; i < 4; i++) {
                    scanf("%hhu.", &networks[k][i]);
                    //checks to see if scanf was working properly
                    //printf(" %hhu", networks[k][i]);
                }
                //printf("\n");
            }
        }
    }
    return (0);
}
 
 
static int compare(const void *a, const void *b, int arg, unsigned char networks[arg][4]) {
    const event *ae = a, *be = b;
    for (int i = 0; i < arg; i++) {
        for (int j = 0; j < 4; j++) {
            if (ae->networks[i][j] < be->networks [i+1][j])
                return -1;
            else 
            if (ae->networks[i][j] > be->networks[i+1][j])
                return 1;
        }
 
        void qsort(void networks, size_t arg, size_t 4,
                   int(*compar)(const void*a, const void *b));
 
    }
}

【问题讨论】:

  • 当两个字段相等(并非所有控制路径都返回值)时,比较函数无法return 0。但我不明白当qsort 规范为 2 时(如您在不必要的声明中所示),您如何能够使用带有 4 个参数的比较器函数。

标签: c sorting multidimensional-array qsort


【解决方案1】:

你应该使用这样的比较函数:

#include <string.h>

int compare_quads(const void *a, const void *b) {
    return memcmp(a, b, 4);
}

并像这样使用它:

//read command line input and store the information
int main(int argc, char *argv[]) {
    //declare variable
    int arg = 0;
 
    //make argv into an int
    if (argc < 2) {
        printf("usage: %s <number>\n", argv[0]);
        return 2;
    }
    arg = atoi(argv[1]);
    //assign size to networks
    unsigned char networks[arg][4];
 
    //assign input to networks
    for (int k = 0; k < arg; k++) {
        for (int i = 0; i < 4; i++) {
             scanf("%hhu.", &networks[k][i]);
        }
    }
    qsort(networks, arg, sizeof(networks[0]), compare_quads);
    //print the networks
    for (int k = 0; k < arg; k++) {
        printf("%d.%d.%d.%d\n", networks[k][0], networks[k][1],
                                networks[k][2], networks[k][3]);
    }
    return 0;
}

【讨论】:

  • qsort 上的 k 是什么?当我尝试运行代码时,它出现为未声明?它只需要声明吗?
  • @Ivickt:很抱歉,应该是 arg 而不是 k。数组中的元素个数。
  • 您能解释一下 compare_quads 函数的作用吗?
  • compare_quads() 使用 memcmp() 比较 4 字节的块。如果a指向的IP地址小于b0指向的IP地址,则返回负数,如果它们相等,即具有相同的4个字节,否则返回正数。 memcmp()strcmp() 类似,但比较固定数量的字节,而不是在空终止符处停止。
  • @Ivickt:您可以通过单击其分数下方的灰色复选标记来接受此答案。