PAT A1028. List Sorting (25)

本文介绍了一个简单的程序设计问题,即如何模仿Excel的排序功能。该程序读取学生的记录(包括ID、姓名和成绩),并根据指定的列对学生记录进行排序。提供了完整的C++代码实现,演示了如何使用比较函数来实现不同条件下的排序。

题目链接

Excel can sort records according to any column. Now you are supposed to imitate this function.

Input

Each input file contains one test case. For each case, the first line contains two integers N (<=100000) and C, where N is the number of records and C is the column that you are supposed to sort the records with. Then N lines follow, each contains a record of a student. A student's record consists of his or her distinct ID (a 6-digit number), name (a string with no more than 8 characters without space), and grade (an integer between 0 and 100, inclusive).

Output

For each test case, output the sorting result in N lines. That is, if C = 1 then the records must be sorted in increasing order according to ID's; if C = 2 then the records must be sorted in non-decreasing order according to names; and if C = 3 then the records must be sorted in non-decreasing order according to grades. If there are several students who have the same name or grade, they must be sorted according to their ID's in increasing order.

Sample Input 1
3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
Sample Output 1
000001 Zoe 60
000007 James 85
000010 Amy 90
Sample Input 2
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
Sample Output 2
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Sample Input 3
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
Sample Output 3
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90
此题属于简单题,只是需要对cmp函数进行活用即可,代码如下:

#include<cstdio>
#include <algorithm>
#include<cstring>
using namespace std;
struct Stu {
    int id;
    char name[10];
    int score;
};
Stu stu[100005];
int c;
bool cmp(Stu a, Stu b) {
    int s;
    switch (c) {
    case 1:return a.id < b.id;
    case 2: s = strcmp(a.name, b.name);
        if (s)return s < 0;
        else return a.id < b.id; 
    case 3: if (a.score != b.score)return a.score < b.score;
            else return a.id < b.id; 
    }
}
int main() {
    int n;
    scanf("%d %d", &n, &c);
    for (int i = 0; i < n; i++) {
        scanf("%d %s %d", &stu[i].id, stu[i].name, &stu[i].score);
    }
    sort(stu, stu + n, cmp);
    for (int i = 0; i < n; i++) {
        printf("%06d %s %d\n", stu[i].id, stu[i].name, stu[i].score);
    }
    return 0;
}



<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、付费专栏及课程。

余额充值