1028. List Sorting (25) PAT甲级

本文介绍了一个使用C语言实现的学生信息排序程序。该程序通过输入学生的ID、姓名和成绩,并允许用户选择不同的排序标准:按ID、姓名或成绩进行排序。程序展示了如何定义结构体来存储学生信息,并使用自定义比较函数实现不同排序方式。

传送门

#include<stdio.h>
#include<algorithm>
#include<string.h>
#define MAX_N 100100

using namespace std;

struct Student{
    int id;
    char name[15];
    int grade;
}stu[MAX_N];

bool cmp1(struct Student a,struct Student b){
    return a.id<b.id;
}

bool cmp2(struct Student a,struct Student b){
    if(strcmp(a.name,b.name)!=0)    return strcmp(a.name,b.name)<0;
    return a.id<b.id;
}


bool cmp3(struct Student a,struct Student b){
    if(a.grade!=b.grade)    return a.grade<b.grade;
    else    return a.id<b.id;
}
int main(){
    int n;
    int choice;
    scanf("%d%d",&n,&choice);
    for(int i=0;i<n;i++){
        scanf("%d %s %d",&stu[i].id,stu[i].name,&stu[i].grade);
    }
    switch(choice){
        case 1:sort(stu,stu+n,cmp1);break;
        case 2:sort(stu,stu+n,cmp2);break;
        case 3:sort(stu,stu+n,cmp3);break;
    }
    for(int i=0;i<n;i++){
        printf("%06d %s %d\n",stu[i].id,stu[i].name,stu[i].grade);
    }
}
<think> 我们将实现一个菜单驱动的程序,包含以下功能: 1. 整数排序和二分查找 2. 浮点数排序和二分查找 3. 字符排序和二分查找 4. 退出程序 对于每个排序和查找部分,我们将: - 首先要求用户输入数组大小。 - 然后输入相应类型的数组元素。 - 对数组进行排序(这里使用qsort函数,因为它高效且标准)。 - 打印排序后的数组。 - 然后要求用户输入一个要查找的元素。 - 使用二分查找在排序后的数组中查找该元素,并输出查找结果。 我们将为整数、浮点数和字符分别编写相应的比较函数,以供qsort和bsearch使用。 注意:由于浮点数比较可能存在精度问题,我们在比较浮点数时使用一个小的epsilon值来判断。 程序结构: - 主循环显示菜单,根据用户选择执行相应操作。 - 每个操作都是一个独立的代码块。 我们将使用以下函数: - int compareInt(const void *a, const void *b) - int compareFloat(const void *a, const void *b) - int compareChar(const void *a, const void *b) 由于菜单需要重复显示直到用户选择退出,我们使用一个循环。 注意:在读取数值后,需要清空输入缓冲区,避免残留的换行符影响后续输入。 我们将使用标准库函数:qsort和bsearch。 然而,bsearch要求数组是排序好的,我们在排序后使用它。 由于浮点数的二分查找需要特别注意精度,我们在比较函数中处理。 但是,在二分查找中,我们仍然使用相同的比较函数,因此对于浮点数,我们使用相同的比较函数,这样能保证一致性。 但是注意:由于浮点数的精度问题,用户输入的要查找的值可能和数组中的值在数学上相等,但二进制表示不同。因此,我们使用一个很小的epsilon(例如0.00001)来比较两个浮点数是否足够接近。 然而,在比较函数中,我们不能直接用相等判断,而是看它们的差的绝对值是否小于一个很小的数。但是,在二分查找中,比较函数返回0表示相等,所以我们在比较函数中实现这个逻辑。 但是,标准二分查找要求严格的有序性,所以我们排序时和查找时使用相同的比较函数,这样即使两个浮点数非常接近(我们认为它们相等),在排序时它们会被视为相等,那么它们的顺序就不重要了。而在查找时,我们也会认为它们相等。 因此,我们定义一个浮点数比较函数,如下: int compareFloat(const void *a, const void *b) { float fa = *(const float*)a; float fb = *(const float*)b; float diff = fa - fb; if (diff < -EPSILON) return -1; if (diff > EPSILON) return 1; return 0; } 其中,EPSILON是一个小的正数,比如1e-5。 对于整数和字符,直接比较即可。 程序步骤: 1. 显示菜单,让用户选择1-4。 2. 根据选择,执行相应的排序和查找操作。 3. 如果选择4,退出程序。 注意:每次操作后,程序会再次显示菜单,直到用户选择4。 由于数组大小是运行时确定的,我们使用动态内存分配(malloc和free)。 为每个类型分别编写代码块。 我们假设用户输入的数据都是有效的,但也要注意错误处理(例如,malloc失败,输入无效数字等)。为了简洁,我们暂不处理输入错误,但会注意基本的输入输出。 代码示例: </think> 以下是针对整数、浮点数和字符的排序与二分查找的C语言实现。程序采用菜单驱动方式,允许用户选择不同的操作类型: ```c #include <stdio.h> #include <stdlib.h> // 比较函数:整数升序 int compareInt(const void *a, const void *b) { return (*(int*)a - *(int*)b); } // 比较函数:浮点数升序(带精度容差) int compareFloat(const void *a, const void *b) { float fa = *(float*)a; float fb = *(float*)b; if (fabs(fa - fb) < 0.00001f) return 0; return (fa > fb) ? 1 : -1; } // 比较函数:字符ASCII升序 int compareChar(const void *a, const void *b) { return (*(char*)a - *(char*)b); } // 二分查找通用实现 int binarySearch(void *arr, int size, int elemSize, void *key, int (*compare)(const void*, const void*)) { int low = 0, high = size - 1; while (low <= high) { int mid = low + (high - low) / 2; void *midElem = (char*)arr + mid * elemSize; int cmp = compare(midElem, key); if (cmp == 0) return mid; // 找到目标 else if (cmp < 0) low = mid + 1; // 目标在右半区 else high = mid - 1; // 目标在左半区 } return -1; // 未找到 } // 打印整数数组 void printIntArray(int arr[], int n) { for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); } // 打印浮点数组 void printFloatArray(float arr[], int n) { for (int i = 0; i < n; i++) { printf("%.2f ", arr[i]); } printf("\n"); } // 打印字符数组 void printCharArray(char arr[], int n) { for (int i = 0; i < n; i++) { printf("%c ", arr[i]); } printf("\n"); } int main() { int choice; do { printf("\n----- 排序与查找系统 -----\n"); printf("1. Integer Sorting and Binary Search\n"); printf("2. Float Sorting and Binary Search\n"); printf("3. Character Sorting and Binary Search\n"); printf("4. Exit Program\n"); printf("请输入选项: "); scanf("%d", &choice); switch(choice) { case 1: { // 整数处理 int n; printf("输入数组元素个数: "); scanf("%d", &n); int *arr = (int*)malloc(n * sizeof(int)); printf("输入%d个整数: ", n); for (int i = 0; i < n; i++) scanf("%d", &arr[i]); qsort(arr, n, sizeof(int), compareInt); printf("排序后: "); printIntArray(arr, n); int key; printf("输入查找目标: "); scanf("%d", &key); int index = binarySearch(arr, n, sizeof
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值