课堂点名系统(西南交通大学C++课程作业)

本文详细描述了如何使用C++实现一个简单的课堂点名系统,涉及班级管理、课表设置、随机点名、学生信息存储和成绩统计等功能,展示了编程中的数据结构和优化技巧。
摘要由CSDN通过智能技术生成

课堂点名系统的制作

以实现老师视角的点名

2024-4-20 进行第一次修改

2024-4-21 由于博主是在Typora写的笔记,拷贝到csdn上出现格式错误,修改格式

2024-4-26 代码从300行变为600行,全部功能简陋实现

一些简单的变量介绍

    首先在我们现实生活中老师上课每个班的人是一定的,因此我们可以先初始化,初定义一些班级的名字以及班级的学生的信息(在这里我使用了一个结构体来表示学生的信息{学生的信息有姓名以及学号其他的我偷懒了没有弄}),同时我们需要enum一下来确定一共有几个班如下

enum banaji { J1 = 1, J2,J3, J4, J5, C1 ,MAX};

这样Max就代表班级的总数,之后我们只需要修改enum就可以修改全部了。

    在初始化完班级后,我们需要简单的东西来代表每一个班(毕竟总不能一直字符串表示一个班吧),因此我选择了使用哈希,因为懒的手写,当了一次调库小子嘻嘻,直接用了map<string,int> , 把班级名字对应成一个独特的数字(这个独特的数字就是他的下标),这样之后我们作为老师修改班级的信息时只需要输入班级的名字,进而我们就能找到班级对应的数字,进而进行修改等等等等之后会继续说。。。

      当然班级的信息应该怎么存,我们需要一个二维数组check[N][N},前面的N代表班级名字对应的hash,后面代表班级成员的名字如下

 map<string, int> name_classbh;     //从名字找到编号下标`
 ​
 `struct student`
 `{`
     `string name;`
     `int xuehao;`
 `};`
 ​
 `student check[110][110] = 
 { 
     {{"李某",2000112471},{"王某",2000112472},{"刘某",2000112473},{"郭某",2000112474},{"何某",2000112475},{"吴某",2000112476},{"赵某",2000112477}},   //可汗大点兵
 };

      后续班级的信息还有班级的人数,我们同样也能用班级名字——>hash的——>班级人数,来得到,这时候你可能会说博主你是不是啥叉,为什么不直接用结构体,嗯~~这是因为懒~~~~~;


       到这里可能还有的朋友是蒙的??博主你在说鸡巴呀我怎么一个字听不懂,因此我们举个例子,比如string name={“ ”,“计算机1班”},比如计算机一班的下标是1吧,hash存一,在我们输入计算机一班时候可以得到1,那么int num={0,7},7的下标是1吧,这样name[hash[计算机一班]]=7,我们就能完美得到想要的数字,当然如果你从头变量name来找到计算机一班的下标也是可以的只是时间复杂度为O\left ( n \right ),哈希应该是O\left ( 1 \right )了;


     好存储班级的信息讲完了,接下来是怎么存课表,同样也是根据现实生活我们可以知道,老师的课表看到的是那一节课哪一个班上课,因此我们可以定义一个lesson[N[N],lesson里面存的值就是班级的hash值,通过时间戳随机数我们来分配课程,具体方法懒得讲了。。。

      其他的就是重复,重复重复,这个东西纯c就可以做了,毕竟只是一个控制台程序,还要细节会在下面说;

1.学期设置

       设置了一个init函数,通过init函数在每次读入一个学期,一周的时候,重新init一下lesson的值,也就是重新用时间戳分配课表

        刚开始我的思路是通过for循环来初始化几个学期几周的值后来发现需要消耗的空间到了可怕的O(n3) 直接放弃,后来想着偷懒要不要直接只弄一个学期的后面几个学期都是这样,不过我的良心告诉我不可以(哈哈哈其实是感觉要是一个老师一辈子都一只是那一个课表那多没意思)。


         最后说个好玩的,这样设置可以查看9999999年1周的课表,让李老师入土了还有课上~~~~~~~

        哈哈地狱级笑话,不过以后不会我快入土了还要敲代码吧(飙汗😓)


2.教学周设置

         教学周设置就像前言说的使用lesson存课表,再来一个函数打印课表就可以了,记得打印班级的名字以及课程编号,而不是打印hash值,像这样——

void Print()
{
    printf("你现在看到的是第%d年%d周的课表\n\n",year,week);
    printf("         星期一 星期二 星期三 星期四 星期五 星期六 星期日\n");
    for (int i = 0; i < 13; i++)
    {
        printf("第%-2d节     ", i+1);
        for (int j = 0; j < 7; j++)
        {
            if (lesson[i][j] != 0)  cout << name[lesson[i][j] - 1] << "   ";
            else cout << "无课   ";
        }
        printf("\n");
        printf("课程编号    ");
        for (int j = 0; j < 7; j++)
        {  
            if (lesson[i][j] != 0)  cout << classbh[lesson[i][j]]<<' ';
            else cout << "       ";
        }
        printf("\n");
        printf("\n");
    }
}

3.教学班的管理

     在这里用了一个bool 变量来节省时间,也就是在init课表时如果这个班级有课那么他的hash对应的bool值就是true,当你输入要添加的班级时可以直接查看他是不是为true,如果不是就在课表上给这个班级加课,这个添加课可以按自己的喜好,我是根据实际来的,比如已经给3班上了两节了那么再后面继续上一节,直到给添加的班上够了3节。。。

     删除的时候更加简单,只需要把删除的班的bool 值变为false,在遍历棋盘的时候可以直接把bool值为false的棋盘值变为0.


     综上在增加或者删除班级时我们的复杂度都可能从o(n2)变为0;

     嘻嘻这可能是胡说,我现在精神失常了,元神启动(我其实不玩游戏)


4.教学班名单管理

     为什么教课的老师还要自己登记上课的学生?不该学校给他吗,离谱!!

     学生的增加和简单,就是在班级名单的后面加上学生的信息就可以了(当然这个可以优化比如学号一样时学生信息作废,这个可以用map<int,bool>来实现,我又又又发懒了就没去做),注意加完了要增加班级的人数!!!

     学生的减少毕竟麻烦,因为数组的删除是很麻烦的(当然链表删除简单),但是我们可以使用一个bool数组来判定这个学生的信息合不合法,当我们删除他时,他的信息不合法,所以我们就直接跳过打印其他学生的信息~~~————————

      最后还要吐槽一下为什么要弄这个 怒怒怒生气生气

5.课程表的设置

      请原谅我读不懂这个和2的区别

6.点名

       终于到重头戏的点名,但是很抱歉我又发懒了,哈哈哈而且还是大懒(主要是我在忙java的事情换赛道的关键时期不想写c++了),因此点名我只是打印出来了那一节课的人名单,具体操作就是输入lesson的横纵坐标,然后然后就没有然后了


       之后可能会继续更新其他的课堂点名奖励机制,其实只是把结构体中学生的信息再加上一个sorce来进行奖励,学生是否迟到也可以稍微确定一个机制玩一玩,比如学生的学号是质数就让他在奇数天迟到哈哈哈,不过为什么我不直接写算法题(额额额),点名的排序其实就是简单的sort排序结构体,不过排序之前记得把学生信息拷贝到一个临时的变量里面,再在临时变量里面进行操作,这样不会改变原排序(记住点名这么弄,如果奖励的话你就只能改变原来的排序了,不过我还没弄就是了。。。)其他的看心情弄吧


         现在更新了,是船新版本了,因为我不懒了(其实是因为在晚自习的时候打不开洛谷还有cf只能被迫写这个。。。)

          好在点名的程序中我们添加了两个小东西==

随机点名

          因为在程序的要求中我们需要我们需要随机点名(提供的随机点名的要求是尽可能点被点次数少的人),因此我们需要在学生的结构体里面加上新的变量来表示被点到的次数,然后我们根据次数排序,不过在这里排序我们不能简单的通过sort排序了(因为如果用sort排序我们的学生信息的下标就改变了,一旦下标改变,会导致我们之前在4.教学名单管理中设置 的学生是否存在的数组的下标的对应出现问题 ,因此我们需要用冒泡排序,在交换学生位置的同时,也交换checkstudent 的下标 , 当然冒泡的时间复杂度确实很大,我们还可以通过类似班级信息的方式通过哈希来优化把时间复杂度从n2 优化为log n , 不过需要注意因为每个学生一定不同的信息为学号而不是姓名,因此我们需要用学号来做hash代表他的信息,不过我发懒了就没做 )————上面介绍的思路在下面排序的时候就不多赘述了。。。

           在打印出来需要点名的名单的时候,我们还需要给出点名的人数,在点完名之后我们再打印一次现在的点名次数方便汇报。。。。好那么我们如何实现判断人是否缺勤呢,其实正规的是在点名的同时输入1代表到达,0代表缺勤,实现并不麻烦,不过在操作的时候比较麻烦,因此我也没做,所以缺勤的次数我就设置为点名的次数除以2(向下取整)。

主动回答问题

          同理我们需要在结构体里面加上学生主动回答问题的次数,打印学生的名单(方便我们知道学生的学号是上面),然后输入学生的学号,然后把整个班的学生遍历一遍(这里又看出来用hash的好处了,有hash的话我们就可以从n的复杂度变为log n,但是我就是懒),找到学生对应的下标,然后给这个学生回答问题的次数++,之后再打印一遍同理。

7.打印总成绩

           最后就是统计总成绩了,我们只需要先打印一遍总的(包括点名的次数,缺勤的次数,回答问题的次数 (如果要出新花样的话我们其实也可以设置一个权值,来看看每个人的平时分是多少)),然后再根据之前的排序方法,排序缺勤次数,回答问题次数并打印。

8.结语

          其实我Typora写的还是很好的就是拷贝到csdn有点变烂这格式(疑惑)

        还有一些细节值得注意,记住变量的命名遵循小驼峰命名(比如name,className),函数的命名遵循大驼峰命名(比如Name,ClassName),不要弄错!!!制作时一定时刻思考如何优化时间和空间复杂度~~~~~~~~

        简单来讲,这个项目就是恶心你恶心恶心你,代码等6月再分享吧,简直就是恶心死我了哈哈哈,想要可以直接私信我(Typora也可以分享)。

  • 36
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值