add: data-structure-lab & compiler-lab

This commit is contained in:
2024-10-30 17:23:52 +08:00
commit eb8c4fa451
35 changed files with 4266 additions and 0 deletions

1
josephus/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.idea/

12
josephus/CMakeLists.txt Normal file
View File

@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
project(josephus)
include_directories(${PROJECT_SOURCE_DIR}/include)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
add_executable(josephus main.cpp ${SRC})

View File

@@ -0,0 +1,82 @@
//
// Created by ricardo on 9/26/22.
//
#ifndef JOSEPHUS_LINKED_LIST_H
#define JOSEPHUS_LINKED_LIST_H
#include "cstdlib"
#include "cstring"
#include "cstdio"
#include "define.h"
/**
* 列表节点结构体
*/
struct node {
int ID;
char Name[MAX_NAME_LENGTH];
int Age;
int Gender;
struct node* next;
};
typedef struct node node_t;
typedef struct node* node_p;
/**
* 创建循环列表
* @param head 头节点地址的引用
* @return true 创建成功
* @return false 创建失败
*/
bool init_linked_list(node_p& head);
/**
* 销毁链表
* @param head 链表头节点的地址
*/
void destroy_linked_list(node_p& head);
/**
* 创建一个链表中的节点
* @param node 新节点地址引用
* @param id 人的编号
* @param age 人的年龄
* @param gender 人的性别
* @param name 人的姓名字符串
* @return true 创建成功
* @return false 创建失败
*/
bool create_node(node_p& node, int id, int age, int gender, char* name);
/**
* 在链表的末尾插入新节点
* 虽然是循环链表 我们不妨认为头节点前的节点
* @param head 链表头节点的引用
* @param new_node 需要插入的新节点
*/
void append_node(const node_p& head, node_p new_node);
/**
* 从链表中删除指定的节点
* @param head 链表头节点的引用
* @param target_node 需要删除的目标节点
* @return true 删除成功
* @return false 删除失败 一般是目标节点非法
*/
bool delete_node(const node_p& head, node_p target_node);
/**
* 打印指定节点记录人员的信息
* @param node 对指定节点的引用
*/
void print_node(const node_p& node);
/**
* 打印链表中每个节点的值
* @param head 链表头节点的引用
*/
void print_linked_list(const node_p& head);
#endif //JOSEPHUS_LINKED_LIST_H

16
josephus/include/define.h Normal file
View File

@@ -0,0 +1,16 @@
//
// Created by ricardo on 2022/9/26.
//
#ifndef JOSEPHUS_DEFINE_H
#define JOSEPHUS_DEFINE_H
// 男性
#define MALE 0
// 女性
#define FEMALE 1
// 姓名字符串的最大长度
#define MAX_NAME_LENGTH 20
#define MAX_GENDER_LENGTH 10
#endif //JOSEPHUS_DEFINE_H

8
josephus/input.txt Normal file
View File

@@ -0,0 +1,8 @@
6
1 zyl male 1
2 zzyl male 2
3 zzzyl female 3
4 zyyl female 4
5 zyyyl female 40
6 zyll female 45
0 4 1

135
josephus/main.cpp Normal file
View File

@@ -0,0 +1,135 @@
//
// Created by ricardo on 9/26/22.
//
#include "LinkedList.h"
#include "define.h"
node_p read_input()
{
int age, id, gender;
char name[MAX_NAME_LENGTH];
char gender_string[MAX_GENDER_LENGTH];
// 性别字符串
const char* male_string = "male";
const char* female_string = "female";
scanf("%d %s %s %d", &id, name, gender_string, &age);
// 匹配输入的性别字符串
if (strcmp(gender_string, male_string) == 0)
{
gender = MALE;
}
else if (strcmp(gender_string, female_string) == 0)
{
gender = FEMALE;
}
else
{
// 如果匹配失败说明输入非法
return nullptr;
}
node_p node;
if (create_node(node, id, age, gender, name))
{
return node;
}
else
{
return nullptr;
}
}
int main() {
// 存储总共的人数
int number;
// 链表的头节点
node_p head;
if (!init_linked_list(head))
{
// 创建链表的头节点
// 如果创建失败输出错误信息
printf("E: Init linked list failed.\n");
return -1;
}
// 输入人员列表
printf("Hint: Enter number of people join this game:");
scanf("%d", &number);
printf("Hint: Enter the people information list as id name gender(male|female) age.\n");
for (int i = 0; i < number; ++i) {
node_p node = read_input();
if (node == nullptr)
{
printf("E: Create Node failed.\n");
return -1;
}
else
{
append_node(head, node);
}
}
// 打印人员列表
print_linked_list(head);
// 分别记录游戏开始的位置 中间的间隔 最后剩余的人数
int begin, middle, left;
printf("Hint: Enter the begin(begin from 0), middle and left people number.\n");
scanf("%d %d %d", &begin, &middle, &left);
node_p node = head->next;
// 循环到达游戏开始的位置
for (int i = 0; i < begin; ++i) {
node = node->next;
}
// 这里有点屎
// 由于给定的数据是"间隔"
// 在遍历时的次数需要+1
// 但是当前被选中的节点会被删除 在删除之间需要将指针下移一位
// 遍历的次序又需要-1
// 故需要在开始前在指针前移一位
node = node->next;
while (number > left)
{
// 游戏开始
// 由于middle是间隔
for (int i = 0; i < middle; ++i) {
if (node == head)
{
// 由于头节点不存储数据
// 遍历到头节点需要多遍历一次
i--;
}
node = node->next;
}
if (node == head)
{
// 如果恰好在末尾遇到head
// 无法在循环中处理
node = node->next;
}
printf("ID:%d was killed\n", node->ID);
node_p target = node;
node = node->next;
if (!delete_node(head, target))
{
printf("E: delete node failed.\n");
return -1;
}
number--;
}
print_linked_list(head);
// 在退出程序之前 释放链表占用的空间
destroy_linked_list(head);
return 0;
}

132
josephus/src/LinkedList.cpp Normal file
View File

@@ -0,0 +1,132 @@
//
// Created by ricardo on 9/26/22.
//
#include "LinkedList.h"
bool init_linked_list(node_p& head)
{
head = (node_p) malloc(sizeof (node_t));
if (head == nullptr)
{
// 空间分配失败
return false;
}
// 由于是创建循环链表 头节点的下一个节点就是头节点
head->next = head;
return true;
}
void destroy_linked_list(node_p& head)
{
node_p node = head->next;
// 先循环处理所有不是头节点的节点
while (node != head)
{
node_p temp = node;
node = node->next;
free(temp);
}
free(head);
head = nullptr;
}
bool create_node(node_p& node, int id, int age, int gender, char* name)
{
node = (node_p) malloc(sizeof(node_t));
if (node == nullptr)
{
// 分配空间失败
return false;
}
node->ID = id;
node->Age = age;
node->Gender = gender;
strcpy(node->Name, name);
return true;
}
void append_node(const node_p& head, node_p new_node)
{
node_p node = head->next;
// 找到头节点前的一个节点
while (node->next != head)
{
node = node->next;
}
node->next = new_node;
new_node->next = head;
}
bool delete_node(const node_p& head, node_p target_node)
{
if (head == target_node)
{
// 删除头节点时不可行的
return false;
}
node_p node = head;
while (node->next != target_node)
{
if (node->next == head)
{
// 循环完了都没找见
// 说明查无此节点
return false;
}
node = node->next;
}
node->next = target_node->next;
free(target_node);
return true;
}
void print_node(const node_p& node)
{
if (node == nullptr)
{
// 指定节点为空
return;
}
printf("ID:%d|", node->ID);
printf("Name:%s|", node->Name);
printf("Age:%d|", node->Age);
if (node->Gender == MALE)
{
printf("Gender:Male\n");
}
else
{
printf("Gender:Female\n");
}
}
void print_linked_list(const node_p& head)
{
if (head == nullptr)
{
// 头节点为空
return;
}
node_p node = head->next;
while (node != head)
{
print_node(node);
node = node->next;
}
}