├── README.md ├── StudentCourse.txt ├── StudentDataBase.cpp ├── StudentDataBase.h ├── StudentInfo.txt ├── main.cpp ├── result.txt └── result_test.txt /README.md: -------------------------------------------------------------------------------- 1 | # 数据库操作的模拟 2 | 3 | **实验要求用ofstream输出的结果在 result.txt 中** 4 | **其余接口的部分测试结果在 result_test.txt 中 (同样也是使用ofstream输出的,其中部分解释是手动输入的)** 5 | 6 | ## 项目需求 7 | 模拟数据库的操作,主要读取`StudentInfo.txt`和`StudentCourse.txt`两张表,其中`StudentInfo.txt` 为学生个人信息表,包括学号 id、姓名 name、性 别 sex、出生年月 birthday、学年 schoolYear、籍贯 birthplace,StudentCourse.txt 为学生选课信息表,包括学号 id、选课 course、学分 credits、分数 score。 8 | 9 | 1. 读入两个文本文件 StudentInfo.txt 和 StudentCourse.txt,使用合适的 STL 数据 结构存储两张表的信息,要求以下的操作效率要高,不建议临时做线性遍历 (即 n 个元素逐一访问)。查询结果需要联表打印出相关信息;如果有多个 条目,默认按照 id 排序。 10 | 11 | 1. 提供排序操作,根据各个字段进行排序,比如 SortByName, SortByScore(单 项课程分数),SortByTotalScore(总分数),支持范围查询,比如查询某门 课分数在 80-90 之间的学生,注意合理设计接口,尽量做到代码简洁,少冗余。 12 | 2. 提供查询和删除操作,根据各个字段进行条件删除。支持多种条件比如`sex == ‘M’ && (birthday.year > 2019 || score < 80)`(不用解析这个字符串表达式),注 意删除要保持两个表格的一致性。 13 | 3. 提供 Test 函数,具体测试以下用例,将结果**通过** **ofstream** **写入**到 result.txt 中 14 | 1. a) 打印 2020 级选修 C 语言且成绩小于 60 分的学生 15 | 2. b) 统计课程平均分大于 80 的学生个人信息并输出 16 | 3. c) 查询每个学生是否修满 20 学分 17 | 18 | **StudentCourse.txt 见文件所示。** 19 | 20 | ## 项目需求在代码中或文档的体现索引: 21 | 22 | 1. 使用stl存储两张表的信息 -- 见前期结构准备 23 | 2. 要求效率高 -- 维护多棵红黑树 -- 保证查找效率 -- 见 前期结构准备 24 | 3. 如果多个条目,默认用id的顺序 -- 查找中返回`set`类型(key是id) -- 默认按照id排好序 25 | 4. 根据每个字段进行排序 -- `Student`中的每个字段都维护了排序方法 -- 见代码,其中`SortByKey`接口维护了多种排序,用传入`SortKey`控制 26 | 5. 支持范围查询 -- 见查找功能 中的第4点 27 | 6. 支持各个字段进行删除 -- 结合查找使用该接口 -- 查找支持各个字段,删除通过利用查找的结果进行删除 28 | 7. 支持结果的交并 -- 见`&`和`|`的重载 29 | 8. 代码已经尽我最大可能把查询的效率维持在`O(logn)`了 30 | 31 | 32 | ## StudentDataBase的实现思路和总体框架 33 | ### 前期结构准备 34 | 1. 首先通过`enum`枚举性别 -- 加强代码的可读性`enum Sex;` 35 | 36 | 2. 通过定义`struct CourseObj;`和`struct Student;`存储`Student`每一个学生的信息 37 | 等题目提供的两个txt文件读取完之后,数据全部统一由`struct Student`结构进行存储 38 | 39 | 3. 所有学生的信息统一存储到一个**哈希表**中 40 | 其中哈希表中的结构为`unordered_map__hash_map;` 41 | `key`为学生的`id` 42 | `value`为指向学生信息的指针 43 | 在本次数据库结构中 -- 全部围绕学生的Id进行操作 44 | **通过哈希表存储学生信息,并以id作为key -- 可以做到通过key找到学生信息的复杂度为O(1)** 45 | 46 | 4. 题目要求通过多个字段查找学生,还需要高效率 47 | 因此我们维护多个`multimap`来同时存储学生的信息 -- 以便保证查询操作的效率可以达到`O(logn)` 48 | 其中,每个`multimap`的`key`为相对应的字段,`value`对应于学生的`id` -- (结合id可以O(1)找到学生的指针,可以完成高效的查询) 49 | 我们一共维护了8个`multimap`(降序`multimap`,通过仿函数`greater`) 50 | 这8个`multimap`我们用一个哈希表封装好 51 | **`unordered_map>>__inner_maps;`** 52 | 这个哈希表的key则为8个`multimap`所对应的标签,分别为: 53 | `"C Programming Language" ,"Advanced math", "College English", 54 | "Control Theory","Python","total_score", "avg_score","birthday"` 55 | 通过该哈希表中的`key`我们可以找到对应的`multimap` 56 | 57 | ### 两个txt文件数据的录入 58 | 1. 数据的录入通过内部`__init_hash_map()`接口和`__init_maps()`完成 59 | 这两个接口中所需的一些工具接口,被封装到了内部类`struct init_tools;`中 60 | 61 | 2. `__init_hash_map()`接口通过读取两个txt文件的每一行,做字符串分析后,`new`出`Student`对象,并插入到哈希表中 62 | 63 | 3. `__init_maps()`接口,通过读取两个txt文件中的每一行,找到对应的id后,在`__hash_map`中找到对应的已经`new`好的`Student`对象,进行数据的录入 64 | 65 | ### 排序功能 66 | 1. 在所有排序接口中 -- 如果要排序的字段已经维护了一棵红黑树,则直接遍历红黑树打印 67 | **复杂度:O(n)** 68 | 2. 在所有排序接口中 -- 如果要排序的字段没有被维护红黑树则取出来 -- 排序后打印。与此同时,需要提供sort的仿函数,例如:`Cmp_SortByName` 69 | **复杂度:O(nlogn)** 70 | 71 | ### 查找功能 72 | 1. 查找功能统一返回`set`类型,为符合条件的`id`的集合 --- 好处:当我们打印多个条目时候 -- 因为`set`的特性,自动按照id排好序了 73 | **这样做的优势:方便交并运算** 74 | **通过id找到学生信息效率很高 -- 为O(1)** 75 | 2. 若查找的字段已经维护了红黑树 -- 直接采用`multimap`的内部接口进行查找:如`multimap::upper_bound,multimap::equal_range` 76 | 3. 若查找的字段没有维护红黑树 -- 则遍历查找 77 | 78 | 4. 支持范围查找的接口有`FindByBirthday()` -- 通过生日查找 79 | `FindByScoreWithKey()`-- 通过分数查找 80 | 其中:`FindByBirthday()`接口: 81 | `FindByBirthday()`接口传入两个元组类型数据结构` (tuple) 82 | set FindByBirthday(const tuple& lower_limit, 83 | const tuple& upper_limit = tuple())` 84 | **其中,第二个元组提供缺省参数** 85 | **使用方法:** 86 | 当第二个参数不传的时候,即`FindByBirthday()`只传入一个tuple -- **表示单个条件查询** 87 | 即查询生日符合第一个元组的学生 88 | 当传入两个参数的时候:分为三种情况: 89 | 1. 如果`lower_limit为(ninf_uint,ninf_uint,ninf_uint)` -- 表示无下限查找 -- 表示只要生日在`upper_limit`之前的都符合条件 90 | 2. 如果`upper_limit为(pinf_uint,pinf_uint,pinf_uint)` -- 表示无上限查找 91 | 3. `lower_limit,upper_limit`中都是其余整数 -- 表示区间查找 92 | 93 | 其中`FindByScoreWithKey()`接口: 94 | `set FindByScoreWithKey(string key, double lower_limit, double upper_limit = INT_MAX)` 95 | 通过key的传入表示要查找的字段,key的选择有: 96 | `"C Programming Language" ,"Advanced math", "College English", 97 | "Control Theory","Python","total_score", "avg_score"` 98 | **使用方法:** 99 | 和`FindByBirthday()`接口一致 100 | 通过区分传入参数个数和值,分别表示 单值查找,无上限查找,无下限查找和区间查找 101 | 102 | ### 删除功能 103 | 通过传入的`set` -- 即学生的id集合进行查找。遍历哈希表(O(1))和8个map (O(n))对指定id的学生进行删除操作。**总的复杂度:O(n)** 104 | 105 | ### 交并功能 106 | **可以调用stl的`set_union`等函数对set完成交并功能,具体请见代码注释。** 107 | 108 | ### 析构 109 | 循环释放哈希表和8个multimap的指针。其中,`Student`需要手动实现析构函数析构`CourseObj*` 110 | 111 | ### 其它接口的功能 112 | 通过注释的形式展示. 113 | -------------------------------------------------------------------------------- /StudentCourse.txt: -------------------------------------------------------------------------------- 1 | #id course credits score 2 | 10917 C Programming Language 3 73 3 | 10919 C Programming Language 3 91 4 | 10914 C Programming Language 3 59 5 | 10908 C Programming Language 3 56 6 | 10921 C Programming Language 3 83 7 | 10905 C Programming Language 3 74 8 | 10917 Advanced math 4 77 9 | 10919 Advanced math 4 76 10 | 10914 Advanced math 4 70 11 | 10908 Advanced math 4 80 12 | 10921 Advanced math 4 79 13 | 10905 Advanced math 4 53 14 | 10917 College English 3.5 90 15 | 10919 College English 3.5 83 16 | 10914 College English 3.5 79 17 | 10908 College English 3.5 80 18 | 10921 College English 3.5 81 19 | 10905 College English 3.5 70 20 | 10917 Control Theory 2 88 21 | 10919 Control Theory 2 86 22 | 10914 Control Theory 2 87 23 | 10908 Control Theory 2 85 24 | 10921 Control Theory 2 90 25 | 10905 Control Theory 2 91 26 | 10917 Python 2 72 27 | 10919 Python 2 81 28 | 10914 Python 2 69 29 | 10908 Python 2 96 -------------------------------------------------------------------------------- /StudentDataBase.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffengc/STL-based-database-operation-simulation-sysu-main/83e41c0b03f0725170e2dfca1b0eb2536499d4bc/StudentDataBase.cpp -------------------------------------------------------------------------------- /StudentDataBase.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffengc/STL-based-database-operation-simulation-sysu-main/83e41c0b03f0725170e2dfca1b0eb2536499d4bc/StudentDataBase.h -------------------------------------------------------------------------------- /StudentInfo.txt: -------------------------------------------------------------------------------- 1 | #id name sex birthday schoolYear birthplace 2 | 10905 xiaomei Female 1999/02/01 2021 hunan 3 | 10908 jianfa Male 1999/07/02 2020 hunan 4 | 10914 dahong Male 2000/02/03 2021 guangdong 5 | 10917 xingfeng Male 2000/02/04 2020 jiangsu 6 | 10919 xiaomi Female 2001/12/05 2019 beijing 7 | 10921 dabin Male 1998/02/06 2018 hainan -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffengc/STL-based-database-operation-simulation-sysu-main/83e41c0b03f0725170e2dfca1b0eb2536499d4bc/main.cpp -------------------------------------------------------------------------------- /result.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffengc/STL-based-database-operation-simulation-sysu-main/83e41c0b03f0725170e2dfca1b0eb2536499d4bc/result.txt -------------------------------------------------------------------------------- /result_test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffengc/STL-based-database-operation-simulation-sysu-main/83e41c0b03f0725170e2dfca1b0eb2536499d4bc/result_test.txt --------------------------------------------------------------------------------