结构体数组成员排序

18

给定一个结构体数组(在C中),我试图按性别分组并按数字顺序分组打印结果。例如:

struct employee{
char gender[13]
char name[13];
int id;
};

假设我这样定义结构数组:

struct employee info[2]={{"male","Matt",1234},{"female","Jessica",2345},{"male","Josh",1235}};

我该如何将结果打印出来,就像这样:

1234 Matt
1235 Josh


2345 Jessica
3个回答

27
您需要实现一个排序函数,该函数按照您的要求比较结构体。
int compare(const void *s1, const void *s2)
{
  struct employee *e1 = (struct employee *)s1;
  struct employee *e2 = (struct employee *)s2;
  int gendercompare = strcmp(e1->gender, e2->gender);
  if (gendercompare == 0)  /* same gender so sort by id */
    return e1->id - e2->id;
  else
    return -gendercompare;  /* the minus puts "male" first as in the question */
}

然后使用标准库中的qsort函数。

qsort(data, count, sizeof(struct employee), compare);

在比较函数中,您可能希望检查id是否相等,然后可以按照您喜欢的方式(还使用strcmp())按名称排序。

编辑:刚刚编译并修复了这个问题。以下是一个小测试程序:

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

    struct employee{
      char gender[13];
      char name[13];
      int id;
    };

    int compare(const void *s1, const void *s2)
    {
      struct employee *e1 = (struct employee *)s1;
      struct employee *e2 = (struct employee *)s2;
      int gendercompare = strcmp(e1->gender, e2->gender);
      if (gendercompare == 0)  /* same gender so sort by id */
        return e1->id - e2->id;
      else
        return -gendercompare;
    }

    main()
    {
      int i;
      struct employee info[]={{"male","Matt",1234},{"female","Jessica",2345},{"male","Josh",1235}};

      for (i = 0; i < 3; ++i)
        printf("%d\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);

      qsort(info, 3, sizeof(struct employee), compare);

      for (i = 0; i < 3; ++i)
        printf("%d\t%s\t%s\n", info[i].id, info[i].gender, info[i].name);
    }

输出结果:

$ ./a.exe
1234    male    Matt
2345    female  Jessica
1235    male    Josh
1234    male    Matt
1235    male    Josh
2345    female  Jessica

1
我认为我们想要“按数字顺序的子排序”。 - dreamcrash
这是一个有点离题的问题,但假设我定义了一个函数。如何将员工信息的内容传递给该函数? - bardockyo
如果有人对此有理解上的困难,可以参考 https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/qsort.htm。 - Suraj Jain

2
在结构数组上使用您喜欢的排序算法。在比较两个元素以决定哪个更大时,请比较它们的性别;如果性别相同,则比较它们的数字。(您可能需要定义一个单独的函数来进行此比较,以使事情更清晰。)之后,使用所需的格式打印排序后的数组。跟踪性别从男性到女性的转换,以便您可以插入三个额外的换行符,就像您的示例一样。
编辑:可以毫不羞耻地从kallikak那里借用一下,只需将您的比较函数传递给qsort,但如果一个结构体“更大”,则返回1,如果它“更小”,则返回-1,如果必要,返回0(使用我上面概述的过程)。请参阅如何编写自定义比较函数的帮助(如何为stdlib中的qsort编写比较函数?)。

谢谢你们两个的回复。我想知道如何在使用排序算法时同时检查性别。例如,如果我正在使用快速排序,如果右边小于左边并且左边是男性,那么应该怎么交换? - bardockyo
请查看我的示例中的比较方法。在决定排序时,您可以检查结构体中的任何字段。 - kallikak

0

我觉得这样更容易理解,因为我对指针不是很熟悉。

#include<bits/stdc++.h>

using namespace std;


struct employee{
  char gender[13];
  char name[13];
  int id;
};

bool compare(employee s1,employee s2)
{
  return s1.id<s2.id;
}

main()
{
  int i;
  struct employee info[]={{"male","Matt",1234},{"female","Jessica",2345},{"male","Josh",1235}};
  sort(info,info+3,compare);
  for (i = 0; i < 3; i++)
  printf("%d\t%s\t%s\n",info[i].id,info[i].gender,info[i].name);
}

1
这不应该是一个C程序吗?看起来你给出了一个CPP版本的代码。 - Jo_L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接