c入门第二十二篇: 学生成绩管理系统查询优化(二分查找)

前言

师弟: “经过几轮优化之后,我的学生成绩管理系统,感觉已经非常不错了,是我学习以来做的最好的系统了。没想到,还是被嘲笑了。”
我:“怎么被嘲笑了?”
师弟:“程夏她说: 你在录入学生的时候,id是增序录入的,在查询的时候,就不能高效一点查询,不去遍历整个数据?”
我:“确定这个女生不是我们计算机系的?”
师弟:“的确不是我们计算机系的呢。”
我:“那人家学习的速度和你相比,像是龟兔赛跑呀。”
看师弟有点难受,我:“干嘛这么惆怅,谁笑的开心还不一定呢。在讲二分查找之前,讲个故事吧。”

龟兔赛跑

乌龟小龟情不自禁的喜欢上了兔子小兔,然后就展开自己快速的步伐,去追小兔,可是小兔的速度太快了,小龟怎么也追不上,小龟爬啊爬,爬啊爬,历经了千山万水,日升日落,春去秋来,小兔的影子都没有看到。
这一天黄昏时分,小龟累了,停留了一下脚步。这个时候,金黄的阳光照射过来,绚丽而灿烂,小龟沉醉在其中,忘记了心中所想,感觉身上满满的都是幸福,闭上了眼睛,尽情的享受着这份快乐。
“你放弃吧。”小龟被一声话语惊醒,本来很生气的小龟,瞬间变得不生气了,替换的更多的是内心的喜悦。因为说话的是小兔,自己满心喜欢和期待的小兔啊。
小龟倔强的回道:“不,我绝不放弃。”但是坚定的说完了以后,小龟内心产生了一个疑问。“真的是决不放弃吗?我能够追的上吗?”疑问很快就被小龟否定了。
“那好吧,你那么笨,既然想追,你就追吧,只要你能够追上我的步伐,那我就可以考虑和你在一起。”说完以后,还没等小龟反应,就已经绝尘而去。
看着小兔远去的背影,夹杂着激起的灰尘,小龟喜中也参含着忧。高兴的是自己有机会,不开心的是自己似乎又没有机会。
小龟重新整理了一下背上的行囊,上路了。目标很明确:追上小兔。
这一年在风吹雨打中过去了。
小龟犹豫了。“我真的能够追上小兔吗?就我这种速度,就我这么笨拙。或许我根本就不适合。或许我该重新认识一下现实,接受现实。”
就在小龟自我否定的时候,不知不觉来到了一个寺庙的门口。门口坐着两个和尚。一个和尚胖胖的,满脸的赘肉,看似很富裕的样子。另一个和尚,有点沧桑,略显消瘦,但是精神饱满。胖和尚惊讶的听着瘦和尚讲述着他去南海的经历。
原来一年前,瘦和尚说道:自己想去南海看看。胖和尚就笑话他,说自己多年前就开始攒钱,常常想着买船,顺江而下,去南海游历一番,可是没有实现,你这么穷,凭什么啊。没想到的是,这个瘦和尚竟然从南海游历回来了。胖和尚没有成功,瘦和尚竟然成功了。
小龟看着瘦和尚的面庞,不知道为什么感觉大受鼓舞,向他拜了拜。“天下事有难易乎?为之则难者亦易矣,不为则易者亦难矣。”小龟轻快的唱着歌就又重新出发了,扫去了之前的不快。
又是一年,伴随着风雨度过。
看着北归的大雁,小龟不知不觉中牵动了归家的情思,眼泪不自觉的流落了下来。
“枯藤老树昏鸦,小桥流水人家,古道西风瘦马,夕阳西下,断肠人在天涯。”一阵悲怆的诗歌从远处被风吹了过来。小龟沿着声音传来的方向看过去,只见一个身形消瘦的长衫游客,牵着一匹瘦瘦的马。不知道为什么小龟内心中很是凄凉。竟然不自觉的在这里放声大哭起来,很是想念在堂的老龟父母。
父母在,不远游。
“归去来兮!”小龟擦干了眼泪,看着夕阳西下,转过了身,朝家的方向爬去。
归家的路好长啊!小龟没有想到这些年竟然走了这么多的路。
终于,到了一条水边,一条熟悉的水边,小的时候曾经来过的地方。站在水边的高处,可以遥遥望见家乡的方向。
不知道为什么,前段时间日夜紧赶,就是想早点回家,这会快要到家了,反而有些羞涩。难道这是“近乡情更怯”。想想自己当年为爱而行,何尝不是在家乡闹得沸沸扬扬。
小龟长舒了一口气,收回了视线,又踏上了回家的路程。
归家途中经过一片农田,在田边不远处有一个老农,手中攥着一个东西,在焦急的等待,眼神紧紧的盯着田边的一棵树桩。
小龟好奇的走过去,问道:“大伯,你这是在等什么吗?”看清了大伯手中的护手后,小龟心头不禁一震。因为这是小龟在几年前送给小兔的生日礼物,这个护手上面有小兔的名字,他一眼就能够认出。为什么小兔的东西会在这儿呢?还没等大伯回答,小龟继续问道:“大伯,你这手中的手环是哪买的啊?好漂亮啊,我也想买一个。”
大伯晃了晃手中的手环,回道:“你说这个啊,不是我买的,是几天前的那个兔子的。”
小龟心头一紧,“前几天的兔子?她怎么了吗?”
大伯笑道:“她跑的太快,一下子撞死在了这棵树桩上了。瞧,血迹还在这儿呢。我在这儿继续等待,看看还有没有兔子过来,那样的话,我也就不用种庄稼了。”
小龟不知道为什么有点眩晕,终于抑制不住伤心,放声大哭了起来。伤心不止,眼泪顺着眼角就流了出来。
大伯看着大哭的乌龟,感觉默名其妙,转身就走了,嘀咕道:“今天,看样子是没有什么收获了,还是回去吧。”
大伯离开以后,小龟哭的更加伤心了,泪眼模糊中似乎看见了小兔的影子,他不顾一切的冲了上去,一把抱住了她,哭喊着说道:“小兔,你为什么,为什么,为什么这么早就离开了。”
“小龟,你这是干什么?”小兔说道,心中说不出的开心。
小龟听到了这话还没有反应过来,擦了擦眼泪。看了看眼前的小兔,不敢相信自己的眼睛。
“你还活着?”小龟兴奋的叫道。
“我当然还活着了,不然你以为呢!”小兔说道。“那滩血迹,是偷我护手的兔子的。走吧,我们回家。回去给你讲这个故事。”
“回家?”小龟疑惑地说道。
“不是说了嘛,只要你追上我,我就和你在一起。你怎么还是这么笨!”小兔说道。
小龟和小兔幸福的回家了。

二分查找

二分查找是一种在有序数组中查找特定元素的算法,其基本思想是将待查找区间分为两部分,每一步比较待查找元素与区间中间元素的大小,从而将搜索范围缩小到一半,又被称为折半查找。

/*** @arr: 有序数组* @l: 待查找区间左端点* @r: 待查找区间右端点* @x: 需要查找的元素*/
int binary_search(int *arr, int l, int r, int x) {while (l <= r) {// 计算中间位置int m = l + (r - l) / 2; // 防止(l+r)直接相加导致的溢出// 检查x是否存在于中间位置if (arr[m] == x)return m;// 若x大,则忽略左半部分if (arr[m] < x) {l = m + 1;} else {// 若x小,则忽略右半部分r = m - 1;}// 若未找到元素,返回-1return -1;
}

完整代码实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for access() function#define MAX_STUDENTS 100
#define MAX_NAME_LEN 50
#define STUDENT_SYSTEM "student_system"
#define TRUE 1
#define FALSE 0typedef struct {int id; // 学号char name[MAX_NAME_LEN]; // 姓名float score; // 成绩
} Student;int student_count = 0; // 学生数量Student *students; // 学生数组指针
int g_max_student = MAX_STUDENTS;Student *stu_sys_init(int num)
{Student *stu_sys;stu_sys = malloc(num * sizeof(Student));if (stu_sys == NULL) {printf("student system malloc failed!\n");}return stu_sys;
}int write_student_info(Student *s)
{FILE *fp = fopen(STUDENT_SYSTEM, "a");if (fp == NULL) {printf("fopen student_system failed!\n");return 1;}fprintf(fp, "%-4d %-10s %-.2f\n", s->id, s->name, s->score);fclose(fp);return 0;
}int check_if_student_exsit(int id)
{int i;for(i = 0; i < student_count; i++) {if(students[i].id == id) {return 1;}}return 0;
}void update_student_info(Student s, int need_write)
{Student *stu_reinit;int old_max_student;int i;if(student_count >= g_max_student) {old_max_student = g_max_student;g_max_student = g_max_student << 1;stu_reinit = stu_sys_init(g_max_student);if (stu_reinit == NULL) {printf("Database is full!\n");return;}memcpy(stu_reinit, students, old_max_student * sizeof(Student));free(students);students = stu_reinit;}if (!check_if_student_exsit(s.id)) {students[student_count++] = s;if (need_write) {printf("Student added successfully, all student: %d!\n", student_count);write_student_info(&s);}} else {printf("student has in db, do nothing!\n");}
}void add_student()
{Student s;printf("Enter student ID: ");scanf("%d", &s.id);printf("Enter student name: ");scanf("%s", s.name);s.score = 0.0; // 初始成绩设置为0update_student_info(s, TRUE);
}void print_title()
{printf("%-4s %-10s %-5s\n", "ID", "Name", "Score");
}void display_all_students()
{int i;printf("-------- All students info --------\n");if (student_count == 0) {printf("No students!\n");} else {print_title();for(i = 0; i < student_count; i++) {printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);}}printf("--------      End       -----------\n");
}/***  * @arr: 有序数组*   * @l: 待查找区间左端点*    * @r: 待查找区间右端点*     * @x: 需要查找的元素*      */
int binary_search(Student *s, int l, int r, int target)
{int m;while (l <= r) {// 计算中间位置m = l + (r - l) / 2; // 防止(l+r)直接相加导致的溢出// 检查x是否存在于中间位置if (s[m].id == target)return m;// 若x大,则忽略左半部分if (s[m].id < target) {l = m + 1;} else {// 若x小,则忽略右半部分r = m - 1;}}// 若未找到元素,返回-1return -1;
}void find_student_by_id()
{int id, i, ret;printf("Enter student ID to search: ");scanf("%d", &id);ret = binary_search(students, 0, student_count, id);if (ret != -1) {print_title();printf("%-4d %-10s %-.2f\n", students[ret].id, students[ret].name, students[ret].score);return;}printf("Student with ID %d not found!\n", id);
}void find_student_by_name()
{int i, is_find = 0;char name[MAX_NAME_LEN];printf("Enter student name to search: ");scanf("%s", name);for(i = 0; i < student_count; i++) {if(strcmp(students[i].name, name) == 0) {print_title();printf("%-4d %-10s %-.2f\n", students[i].id, students[i].name, students[i].score);is_find = 1;}}if (is_find == 0) {printf("Student with name %s not found!\n", name);}
}void add_score()
{int id, i;float score;printf("Enter student ID: ");scanf("%d", &id);printf("Enter student score: ");scanf("%f", &score);for(i = 0; i < student_count; i++) {if(students[i].id == id) {students[i].score = score;printf("Score added successfully!\n");return;}}printf("Student with ID %d not found!\n", id);
}void display_average_score()
{float total = 0.0;int i;for(i = 0; i < student_count; i++) {total += students[i].score;}printf("Average score of all students: %.2f\n", total / student_count);
}int init_student_info()
{if(access(STUDENT_SYSTEM, F_OK) != 0) { // 文件不存在return 0;}FILE *fp = fopen(STUDENT_SYSTEM, "r");if (fp == NULL) {printf("fopen student_system failed!\n");return 1;}#define BUF_SIZE 1024char buf[BUF_SIZE];int i = 0;Student s;while(fgets(buf, BUF_SIZE - 1, fp) != NULL) {sscanf(buf, "%d %s %f\n", &s.id, s.name, &s.score);update_student_info(s, FALSE);}fclose(fp);return 0;}void swap(Student *a, Student *b)
{Student tmp = *a;*a = *b;*b = tmp;
}void bubble_sort_by_score(Student *s, int n)
{int i, j;for (i = 0; i < n-1; i++) {for (j = 0; j < n-i-1; j++) { // 最后 i 个已经排序好了, 遍历未排序的部分if (s[j].score < s[j+1].score) {// 如果当前元素大于后面的元素,交换它们swap(&s[j], &s[j+1]);}}}
}int main()
{int choice;int ret;students = stu_sys_init(MAX_STUDENTS);if (students == NULL) {printf("student system init failed, exit!\n");return -1;}ret = init_student_info();if (ret) {printf("init_student_info failed!\n");return 1;}display_all_students();do {printf("\nStudent Score Management System\n");printf("0. Exit\n");printf("1. Add Student\n");printf("2. Display All Students\n");printf("3. Find Student by ID\n");printf("4. Find Student by Name\n");printf("5. Add Score\n");printf("6. Display Average Score\n");printf("7. Display by Score sort\n");printf("Enter your choice: ");scanf("%d", &choice);switch(choice) {case 0:printf("Exiting...\n");break;case 1:add_student();break;case 2:display_all_students();break;case 3:find_student_by_id();break;case 4:find_student_by_name();break;case 5:add_score();break;case 6:display_average_score();break;case 7:bubble_sort_by_score(students, student_count);display_all_students();break;default:printf("Invalid choice!\n");}} while(choice != 0);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/699115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跟我学C++中级篇——C++17标准后的std::invoke系列

一、函数调用方式 在学习编程的开始&#xff0c;就接触到了函数和函数的调用。可以这样讲&#xff0c;不会调用函数&#xff0c;那么最基础的语言功能便无法使用了。无论是低级到汇编或者高级到哪个语言&#xff0c;函数仍然是其重要的基础一环。可能随便一个学习过编程的都可…

动态规划算法学习(基础)

做题步骤&#xff1a; 确定dp数组的含义(一维或者二维) 获取递推公式 dp数组如何初始化 确定遍历顺序 打印dp数组&#xff08;检查&#xff09; 题目&#xff1a; 1. 斐波那契数 509 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 …

留子厨房开发日志

以下记录了使用go语言框架Beego&#xff0c;Mysql数据库&#xff0c;Redis数据库实现一个点菜/菜谱应用API的全过程。 技术方案 github地址 数据库设计 新建数据库&#xff1a; CREATE DATABASE menu;新建数据表&#xff1a; CREATE TABLE menu ( id int(10) unsigned NOT …

2024 CKS 题库 | 11、AppArmor

不等更新题库 CKS 题库 11、AppArmor Context: APPArmor 已在 cluster 的工作节点node02上被启用。一个 APPArmor 配置文件已存在&#xff0c;但尚未被实施。 Task: 在 cluster 的工作节点node02上&#xff0c;实施位于 /etc/apparmor.d/nginx_apparmor 的现有APPArmor 配置…

Python 实现 ADTM 指标计算:股票技术分析的利器系列(9)

Python 实现 ADTM 指标计算&#xff1a;股票技术分析的利器系列&#xff08;9&#xff09; 介绍算法解释 核心代码rolling函数介绍计算 DTMnp.where 使用介绍np.maximum 计算 DBM计算 STM计算 SBM计算 ADTM 完整代码 介绍 ADTM&#xff08;动态买卖气指标&#xff09;是一种用…

C++奇怪的 ::template

答疑解惑 怎么会有::template的写法 起初 在阅读stl的源码的时候&#xff0c;发现了一条诡异的代码 // ALIAS TEMPLATE _Rebind_alloc_t template<class _Alloc,class _Value_type> using _Rebind_alloc_t typename allocator_traits<_Alloc>::template rebind…

【misc | CTF】攻防世界 simple_transfer

天命&#xff1a;这题其实不简单啊 拿到流量包&#xff0c;丢进去wireshare&#xff0c;题目都说了flag在里面 ctrl f 直接搜索字符串 右键&#xff0c;追踪流 -> TCP流 查找 .pdf 文件&#xff0c;其实这里思路是比较奇怪的&#xff0c;毕竟是的确比较多内容&#xff0c…

基于PostGIS的慢查询引起的空间索引提升实践

目录 前言 一、问题定位 1、前端接口定位 2、后台应用定位 3、找到问题所在 二、空间索引优化 1、数据库查询 2、创建空间索引 3、geography索引 4、再看前端响应 总结 前言 这是一个真实的案例&#xff0c;也是一个新入门的工程师很容易忽略的点。往往在设计数据库的…

NestJS入门4:MySQL typeorm 增删改查

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 1. 安装数据库相关模块 npm install nestjs/typeorm typeorm mysql -S 2. MySql中创建数据库 ​ 3. 添加连接数据库代码 app.module.ts ​ import { M…

给自己留个备忘,blender是右手坐标系

所谓右手坐标系&#xff0c;就是三个轴的方向和右手三根手指的方向一致&#xff08;当然&#xff0c;有要求的&#xff0c;这个要求是大拇指指向x轴方向&#xff0c;食指指向y轴方向,中指指向z轴方向&#xff09;。 不过blender默认是z轴朝上的&#xff0c;如下图。 右手坐标系…

element导航菜单el-menu添加搜索功能

element导航菜单-侧栏&#xff0c;自带的功能没有搜索或者模糊查询。 找了找资料 找到一个比较可行的&#xff0c;记录一下&#xff1a; //index.vue的代码 <div style"overflow:auto"><el-menu :default-active"$route.path":default-openeds&…

<网络安全>《49 网络攻防专业课<第十三课 - 华为防火墙的使用(2)>

6 防火墙的防范技术 6.1 ARP攻击防范 攻击介绍 攻击者通过发送大量伪造的ARP请求、应答报文攻击网络设备&#xff0c;主要有ARP缓冲区溢出攻击和ARP拒绝服务攻击两种。 ARP Flood攻击&#xff08;ARP扫描攻击&#xff09;&#xff1a;攻击者利用工具扫描本网段或者跨网段主机时…

构造器详解

定义: 是一种特殊类型的方法&#xff0c;用于创建对象时初始化对象的状态。 使用new关键字创建对象 构造器特点: 1.和类名相同 2.没有返回值 public class Person {String name;public Person() {this.name"John";}}public class Test {public static void main…

vue2+element医院安全(不良)事件报告管理系统源代码

目录 安全不良事件类型 源码技术栈 医院安全&#xff08;不良&#xff09;事件报告管理系统采用无责的、自愿的填报不良事件方式&#xff0c;有效地减轻医护人员的思想压力&#xff0c;实现以事件为主要对象&#xff0c;可以自动、及时、实际地反应医院的安全、不良、近失事件…

音视频技术-网络视频会议“回声”的消除

目录 一、“回音”的成因原理 二、解决思路 三、解决方案 1、方案一 2

测试环境搭建整套大数据系统(六:搭建sqoop)

一&#xff1a;下载安装包 https://archive.apache.org/dist/sqoop/ 二&#xff1a;解压修改配置。 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /opt cd /opt mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop-1.4.7修改环境变量 vi /etc/profile#SQOOP_HOME export SQOOP_…

【K8s】-- 描述容器中 pod 的状态

命令&#xff1a;kubectl describe pod -n 你的namespace名称 pod 名称 举例&#xff1a;kubectl describe pod -n my-flink --context prod-5 test-record-all-new-mc-taskmanager-1-1 Name: test-record-all-new-mc-taskmanager-1-1 Namespace: ky-flink Pri…

Mybatis总结二

重复的类我们用工具把它包装起来&#xff1a; public class MybatisUtils {private static SqlSessionFactory factory null;static{String config "mybatis.xml";try {InputStream in Resources.getResourceAsStream(config);factory new SqlSessionFactoryBui…

nginx-------- 高性能的 Web服务端 (四)

一、高级配置 1 .1网页的状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机…

使用和管理jupyter notebook, anaconda环境下在jupyter使用自己创建的虚拟环境,怎么删除jupyter其他内核

引言&#xff1a;我有GPU&#xff0c;之前也下载了cuda&#xff0c;但是在jupyter中不能使用gpu&#xff0c;原因是我下载的cuda在另一个虚拟环境pytorch中&#xff0c;但是pytorch这个虚拟环境没有加到jupyter的内核中&#xff0c;怎么在jupyter使用自己创建的虚拟环境看二.an…