IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Student List for Course (25) -> 正文阅读

[数据结构与算法]Student List for Course (25)

前言

《算法笔记》 vector的使用


一、题目分析

题目见:http://codeup.hustoj.com/problem.php?cid=100000596&pid=1
大致题意:给出每个学生的选课表,求出每门课程的学生名单

二、需求分析

1.输入分析

每个输入文件包含一个测试用例。
第一行输入学生总数N(<=40000)和课程总数K(<=2500)。
然后输入N行数据,每行包含学生名字(3个大写字母加一位数字(0~9))、一个正整数C(<=20,是学生注册的课程数)、C个课程编号(从1到K)。

2.输出分析

按课程编号升序输出每门课的学生名单。每门课程首先将课程编号和注册人数在一行中输出,然后字典序输出学生名字,每个名字占一行。

3.功能分析

(1)输入学生的课程信息
(2)分析每门课的选课名单
(3)输出课程的学生名单

4.测试用例

输入:

10 5
ZOE1 2 4 5
ANN0 3 5 2 1
BOB5 5 3 4 2 1 5
JOE4 1 2
JAY9 4 1 2 5 4
FRA8 3 4 2 5
DON2 2 4 5
AMY7 1 5
KAT3 3 5 4 2
LOR6 4 2 4 1 5

输出:

1 4
ANN0
BOB5
JAY9
LOR6
2 7
ANN0
BOB5
FRA8
JAY9
JOE4
KAT3
LOR6
3 1
BOB5
4 7
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
5 9
AMY7
ANN0
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1

三、概要设计

1.数据结构

通过字符串hash将学生名字映射为整数,名字可使用整数保存。
课程的学生名单使用二维整型数组保存。
学生的课程信息也可以使用二维整型数组来进行保存。

2.基本操作

基本操作操作结果
name_to_id()将名字转换为整数id
id_to_name()将整数id转换为名字
course_list_fit()输入学生的课表,构建出课程的学生名单
course_list_out()输出课程的学生名单

3.程序模块及调用图

(1)主程序模块main()
(2)名字转换id模块name_to_id()
(3)id转换名字模块id_to_name()
(4)课表构建模块course_list_fit()
(5)课程名单输出模块course_list_out()
模块调用图 :
在这里插入图片描述

四、详细设计

1.数据结构

课表使用二维整数数组来保存,第一维维度为2500,代表课程,0 ~ 2499对应1 ~ 2500的课程,第二维使用vector,保存每个学生名字的id。

2.各模块详细设计

(1)主程序模块
首先调用课程构建模块通过学生的课表分析出课程的学生名单,然后调用课程名单输出模块。
(2)名字转换id模块
前3位是二十六进制数,后一位是十进制数
名字前三位减去字符‘A’,后一位减去字符’0‘
C1C2C3C4
hash(C1C2C3C4)=C1 * 262 * 10+C2 * 26 * 10+C3 * 10 +C4=((C1*26+C2) *26+C3) *10+C4
通过这个公式计算出id即可。
(3)id转换名字模块
名字转换id的逆过程。
(4)课表构建模块
通过输入的课程编号确定课表的对应位置(编号-1),将对应的名字通过name_to_id()得到id保存到课表里。
(5)课程名单输出模块
遍历课表,将学生id升序排列(由hash构建过程可知即为名字的字典序),名字的输出通过调用id_to_name()。

五、代码编写

#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

const int maxn=2500;
vector <int> course[maxn];
int N,K;

int name_to_id(char name[5]){
    int id=0;
    for(int i=0;i<=2;i++){
        id=id*26+(name[i]-'A');
    }
    id=id*10+name[3]-'0';
    return id;
}

void id_to_name(int id,char name[5]){
    name[4]='\0';
    name[3]=id%10+'0';
    id=id/10;
    for(int i=2;i>=0;i--){
        name[i]=id%26+'A';
        id=id/26;
    }
}

void course_list_fit(){
    char name[5];
    int course_num;
    int index;

    scanf("%d %d",&N,&K);

    for(int i=0;i<N;i++){
        scanf("%s",name);
        scanf("%d",&course_num);
        int id=name_to_id(name);
        while(course_num--){
            scanf("%d",&index);
            course[index-1].push_back(id);
        }
    }
}

void course_list_out(){
    int i,j;
    char name[5];
    for(i=0;i<K;i++){
        int index=i+1;
        printf("%d %d\n",index,course[i].size());
        sort(course[i].begin(),course[i].end());
        vector <int>::iterator it=course[i].begin();
        for(;it!=course[i].end();it++){
            id_to_name(*it,name);
            printf("%s\n",name);
        }
    }
}


int main(){
    course_list_fit();
    course_list_out();
    return 0;
}

六、总结

1.遇到的问题

(1)程序不输出学生的名字,将id转换为名字时函数返回指针是空的
出现问题的原代码如下 :

char* id_to_name(int id){
	char name[5];
    name[4]='\0';
    name[3]=id%10+'0';
    id=id/10;
    for(int i=2;i>=0;i--){
        name[i]=id%26+'A';
        id=id/26;
    }
}

分析:
该思路是将函数内的name字符数组的指针作为返回值,进而得到解析出的名字。
但是由于name在该函数中是局部变量,在函数调用完成后name指向的内容被释放,name变为空指针,并不能实现返回的效果。这里的局部变量实际上是在栈空间里面。
解决方法:
只要name数组在函数调用后空间不被释放即可。

①将字符数组作为函数的形参
②使用malloc()分配空间,但要注意将其空间在合适的时候释放
③使用static修饰字符数组变量(静态局部变量)
④全局变量

(2)程序输出的名字是错误的,和预期不符
分析:
名字错误说明hash映射函数模块出了问题,经检查是在将名字转换为整数时末位忘记赋值了,得到了错误的转换结果。改正解决。

2.收获

(1)栈在内存中有高地址向低地址生长,在函数调用前栈基址(ebp)和栈顶地址(esp)都会被压入栈中,是为了能够在调用结束后能够恢复到原来的状态。结束调用后相当于调用函数时保存在栈中的变量均被释放,不能够继续使用。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:53:24  更:2021-08-12 16:58:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 3:43:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码