提问人:stephanp 提问时间:11/10/2023 最后编辑:Allan Windstephanp 更新时间:11/10/2023 访问量:60
如何按字母顺序对多个“人”字符串进行排序,而不会将它们移动到不同的“座位”?
How do I alphabetically sort multiple 'people' strings without them moving to different 'seats'?
问:
我正在用 C 语言编写一个座位预订程序,其中包含一个选项,其中分配给其座位的乘员可以按字母顺序排序。当我选择对它们进行排序的选项时,该函数确实按字母顺序对姓氏和名字进行排序,但是,在此过程中,会获取姓氏和名字参数并将它们移动到不同的席位。
我目前正在使用 qsort 函数对存储在名为“SEAT”的结构中的名称进行排序,该结构包含名字和姓氏字符以及席位 ID 和分配的整数。
SEAT结构:
typedef struct seat { // struct used to hold all SEAT variables
int seatID;
int occupied;
char lastname[MAXNAME];
char firstname[MAXNAME];
} SEAT;
qsort 函数位于名为“alphasortSeat”的较大函数中,并使用另外两个名为“lastnameCompare”和“firstnameCompare”的函数作为其 CompareFuncion 参数。
我希望这个函数在调用时按名字或姓氏按字母顺序对姓名进行排序,而不会将数据移动到看似随机的座位分配中。
例如: 1号座位分配给:鲍勃·詹金斯,2号座位分配给:习近平。
调用并执行函数后,名称按字母顺序排序,但现在会打印:
座位 1 分配给 Bob Jenkins
7号座位分配给习
(实际上,这两个名字现在已分别移至11号座位和12号座位。
这是我目前使用的代码:
main.c:
scanf_s(" %c", &choice[0], MAXCHOICELEN);
switch (choice[0]) {
//.....
case 'c':
alphasortSeat(seats, MAXSEAT); // sorting the occupants by alphabetical order
break;
//.....
library.c:
//.....
功能比较:
int lastnameCompare(const void* a, const void* b) { // function that compares lastname(s) in order to properly sort them later on alphabetically
const SEAT* seatA = (const SEAT*)a;
const SEAT* seatB = (const SEAT*)b;
return strcmp(seatA->lastname, seatB->lastname);
}
int firstnameCompare(const void* a, const void* b) { // function that compares firstname(s) in order to properly sort them later on alphabetically
const SEAT* seatA = (const SEAT*)a;
const SEAT* seatB = (const SEAT*)b;
return strcmp(seatA->firstname, seatB->firstname);
}
按字母顺序排序功能:
void alphasortSeat(SEAT seats[], int seatNum) { // alphabetically sort names function
char alphaChoice;
printf("Sort by first or last name (f or l): ");
scanf_s(" %c", &alphaChoice, MAXCHOICELEN);
if (alphaChoice == 'f') {
qsort(seats, seatNum, sizeof(SEAT), firstnameCompare); // qsort functions used to order the letters
// qsort_s not used, "context" parameter (MAXSEAT) caused warnings (not needed).
for(int i = 0; i < seatNum; i++){
if (seats[i].occupied) {
printf("\n %s %s is assigned to seat %d.", seats[i].firstname, seats[i].lastname, seats[i].seatID);
}
}
}
else if (alphaChoice == 'l') {
qsort(seats, seatNum, sizeof(SEAT), lastnameCompare);
for (int i = 0; i < seatNum; i++) {
if (seats[i].occupied) {
printf("\n %s %s is assigned to seat %d.", seats[i].lastname, seats[i].firstname, seats[i].seatID);
}
}
}
else {
fprintf(stderr, "\n\nERROR: Invalid character entered.\n\n"); // error statement for invalid character
return;
}
}
//.....
library.h:
int lastnameCompare(const void* a, const void* b);
int firstnameCompare(const void* a, const void* b);
void alphasortSeat(SEAT seats[], int seatNum);
我觉得主要问题是我没有正确使用 qsort,或者我的比较函数没有像它们应该的那样完成它们的工作。我只是 C 语言的初学者,我很好奇为什么我的代码会产生如此奇怪的错误。
答:
我无法重现您的问题。由于您是这里的新手,下面将是一个最小的非交互式代码示例,可以轻松为您提供帮助。如果您不需要同时使用 firstname 和 lastname 排序来演示问题,请省略其中一个。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNAME 42
typedef struct seat {
int seatID;
int occupied;
char lastname[MAXNAME];
char firstname[MAXNAME];
} SEAT;
#define genFieldCompare(field) \
int field ## Compare(const void *a, const void *b) {\
const SEAT *seatA = a;\
const SEAT *seatB = b;\
return strcmp(seatA->field, seatB->field);\
}
genFieldCompare(firstname);
genFieldCompare(lastname);
#undef genFieldCompare
void printSeat(const SEAT seats[], int seatNum) {
for(int i = 0; i < seatNum; i++)
if (seats[i].occupied)
printf("%s %s is assigned to seat %d.\n", seats[i].firstname, seats[i].lastname, seats[i].seatID);
printf("\n");
}
int main(void) {
SEAT seats[] = {
{2, 1, "AXi", "Jinping"},
{1, 1, "Jenkins", "Bob"}
};
const size_t seatNum = sizeof seats / sizeof *seats;
qsort(seats, seatNum, sizeof *seats, firstnameCompare);
printSeat(seats, seatNum);
qsort(seats, seatNum, sizeof *seats, lastnameCompare);
printSeat(seats, seatNum);
}
按照惯例,所有大写符号 (SEAT) 都是为符号常量(和枚举值)保留的。如果不需要,只需省略并将其用作符号名称即可。struct seat
seat
typedef
花哨的宏只是为了使代码更短一些,并确保它们以完全相同的方式实现,而不是两个不同的字段名称。genFieldCompare
输出示例:
Bob Jenkins is assigned to seat 1.
Jinping AXi is assigned to seat 2.
Jinping AXi is assigned to seat 2.
Bob Jenkins is assigned to seat 1.
为了重现您的问题,我希望 Bob 不再被分配座位 1,而类似的 Jingping 不再被分配座位 2。
评论