arrays - 通过结构和函数进行数组排序
问题描述
这是我目前正在处理的函数,它与 qsort 函数非常相似。如果数组已排序,则此函数返回 true,否则返回 false。我正在努力解决的问题是弄清楚如何通过数组并调用作为参数给出的比较函数。
我的主要目标是比较数组的每个相邻值,如果 > 0,则返回 false。(注意:这是因为我的比较函数类似于 qsort 函数,如果第一个值更大则返回 1,如果小于则 -1,如果相同则返回 0)。
1.) 如果参数为空,我将如何调用比较函数?另外,我如何每次调用数组“stu”并比较每个部分(ID、名字、姓氏)?我需要 3 个 if 语句吗?
bool areStudentsSorted(Student * stu, int numelem, int (*compar)(const void *, const void *)) {
for (int i = 0; i <= numelem; i++){
if (compar(i,i+1) > 0){ <- incorrect
//stuck
return true;
}
这里有两种调用函数的方法
if (!areStudentsSorted(stu, numelem, compareFirstName)) {
return EXIT_FAILURE;
}
if (!areStudentsSorted(stu, numelem, compareLastName)) {
return EXIT_FAILURE;
这是一个比较函数的例子
int compareLastName(const void * p1, const void * p2)
{
const Student *stu1, *stu2;
stu1 = p1;
stu2 = p2;
return strcmp(stu1->lastname, stu2->lastname);
}
最后,这是结构体 Student
typedef struct
{
int ID;
char firstname[NAME_LENGTH] ;
char lastname[NAME_LENGTH] ;
} Student;
解决方案
如果参数为空,我将如何调用比较函数?
参数不是void
,它们是void *
。当您为参数传递一个指针时void *
,您可以传递任何类型的指针。它将被隐式转换为void *
参数。
但是,您的函数调用不正确:
compar(i,i+1)
变量i
不是指针,它是表示数组索引的整数。相反,您应该传递一个指向Student
结构的指针。所以你应该写
compar( &stu[i], &stu[i+1] )
反而。该&
运算符是“地址”运算符。
另外,你应该改变
for (int i = 0; i <= numelem; i++){
至
for (int i = 0; i < numelem - 1; i++){
否则您将越界访问数组。
另外,我如何每次调用数组“stu”并比较每个部分(ID、名字、姓氏)?我需要 3 个 if 语句吗?
如果您希望比较函数在确定排序顺序时考虑所有 3 个字段,那么您必须决定应根据哪些标准对学生进行排序。例如,您可能希望学生主要按姓氏排序,如果多个学生的姓氏相同,则应按名字排序,如果多个学生的姓氏和名字相同,您可能希望他们将根据他们的ID进行排序。在这种情况下,您可以编写一个相应的比较函数,该函数将所有 3 个标准都考虑在内:
int compareByAllThreeCriteria( const void * p1, const void * p2 )
{
int ret;
//compare last name
ret = compareLastName( p1, p2 );
if ( ret != 0 )
return ret;
//last name is identical, so it should be sorted by first name
ret = compareFirstName( p1, p2 );
if ( ret != 0 )
return ret;
//both names are identical, so it should be sorted by ID
return compareID( p1, p2 );
}
您还可以将函数compareLastName
,compareFirstName
和组合compareID
成一个大的比较函数:
int compareByAllThreeCriteria( const void * p1, const void * p2 )
{
const Student *stu1, *stu2;
stu1 = p1;
stu2 = p2;
int ret;
//first compare the last name
ret = strcmp(stu1->lastname, stu2->lastname);
if ( ret != 0 )
return ret;
//last name is identical, so it should be sorted by first name
ret = strcmp( stu1->firstname, stu2->firstname );
if ( ret != 0 )
return ret;
//both names are identical, so it should be sorted by ID
if ( stu1->ID < stu2->ID )
return -1;
if ( stu1->ID > stu2->ID )
return +1;
//if they are not smaller or greater, they must be equal
return 0;
}
推荐阅读
- r - 如何将每列乘以 R 中的每个标量?
- python - Python使用sympy求解三次方程
- python - 在 Django >= 1.8 中使用 argparser 而不是 OptParser
- css - 为什么这个不有一个非零宽度?
- scala - 是否有用于对没有共同祖先的类进行分组的“OneOf”类
- android - 运行使用 JNI / NDK 的自定义 Android 系统应用程序
- python - Python中的进程间内存文件系统?
- c - BST 树问题 - C 语言
- javascript - 使用 react 发送带有状态信息的电子邮件
- rcpp - 在 Rcpp 中,如何将用户定义的结构从 C 获取到 R