From f0f66caf474a33caad0887a13a95938d8e6fd598 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 22 Sep 2025 22:20:44 +0800 Subject: [PATCH 001/106] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c25037..3ab7e30 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # Software-Introduction-Personal-Project - +# 啦啦啦 -- 2.34.1 From 77e2fd402948531df6852ce34ca94816ed825cb7 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 22 Sep 2025 22:21:24 +0800 Subject: [PATCH 002/106] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ab7e30..d5aad45 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # Software-Introduction-Personal-Project -# 啦啦啦 +# 调试版本 + -- 2.34.1 From b20ce81dbb989d76234a55e23ab194c793abe1ba Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 22 Sep 2025 22:38:01 +0800 Subject: [PATCH 003/106] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5aad45..76b5e28 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # Software-Introduction-Personal-Project -# 调试版本 +## 调试版本 -- 2.34.1 From 9c94f53419c9e5bce4eec909f1a2d5ef33dcdc2a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 10:39:22 +0800 Subject: [PATCH 004/106] =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E5=88=86=E6=9E=90.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76b5e28..839034f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,56 @@ -# Software-Introduction-Personal-Project -## 调试版本 +# 软件需求分析 + +## 1. 引言 + +该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 + +## 2. 功能需求 + +### 2.1 用户登录功能 +- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 +- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 +- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 + +### 2.2 题目生成功能 +- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 +- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 +- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 + +### 2.3 避免重复题目 +- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 + +### 2.4 账号类型切换功能 +- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 +- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 + +### 2.5 退出功能 +- **输入**:用户输入-1以退出当前登录状态并重新登录。 + +## 3. 系统架构设计 + +### 3.1 用户登录模块 +- **输入**:用户名和密码 +- **处理**:验证用户输入,确认是否匹配预设账号 +- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 + +### 3.2 题目生成模块 +- **输入**:题目数量和账户类型 +- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 + +### 3.3 文件管理模块 +- **输入**:生成的题目 +- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 +- **输出**:生成的题目文件保存在指定的文件夹中。 + +### 3.4 账号类型切换模块 +- **输入**:切换命令“切换为 XX” +- **处理**:修改当前账号类型并更新题目生成模式。 + +### 3.5 错误处理和提示模块 +- **输入**:用户的各种操作 +- **处理**:根据不同情况给出详细的错误提示和操作提示。 + +## 4. 数据库设计 + +由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 -- 2.34.1 From 8d503313fee1108c664c86ba7f751c0097be1a80 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 14:47:15 +0800 Subject: [PATCH 005/106] =?UTF-8?q?Add=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 类的设计.md diff --git a/类的设计.md b/类的设计.md new file mode 100644 index 0000000..fb24237 --- /dev/null +++ b/类的设计.md @@ -0,0 +1 @@ +#类的设计 \ No newline at end of file -- 2.34.1 From 09fb3caeb909733f81a0f0c34ddaba8151a6c647 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 14:59:31 +0800 Subject: [PATCH 006/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/类的设计.md b/类的设计.md index fb24237..df2a8e4 100644 --- a/类的设计.md +++ b/类的设计.md @@ -1 +1,19 @@ -#类的设计 \ No newline at end of file +#类的设计 +##User +###作用: + 存储用户账户信息,包括用户名、密码和用户类型 +###属性: + private String username; // 用户名 + private String password; // 密码 + private UserType userType; // 用户类型(小学/初中/高中) +###方法: + public boolean validateCredentials(String inputUsername, String inputPassword) + // 验证用户名和密码是否匹配 + + // Getter和Setter方法 + public String getUsername() + public void setUsername(String username) + public String getPassword() + public void setPassword(String password) + public UserType getUserType() + public void setUserType(UserType userType) -- 2.34.1 From ed91cc8cfc616952616873d00c9a61821f5ed417 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 15:11:38 +0800 Subject: [PATCH 007/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/类的设计.md b/类的设计.md index df2a8e4..554fc79 100644 --- a/类的设计.md +++ b/类的设计.md @@ -5,7 +5,7 @@ ###属性: private String username; // 用户名 private String password; // 密码 - private UserType userType; // 用户类型(小学/初中/高中) + private String userType; // 用户类型(小学/初中/高中) ###方法: public boolean validateCredentials(String inputUsername, String inputPassword) // 验证用户名和密码是否匹配 -- 2.34.1 From a97ba049986de9d82a7aae22d4897058104aebc4 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 15:55:37 +0800 Subject: [PATCH 008/106] =?UTF-8?q?Add=20=E4=BF=AE=E6=94=B9AI.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 修改AI.md diff --git a/修改AI.md b/修改AI.md new file mode 100644 index 0000000..28c5998 --- /dev/null +++ b/修改AI.md @@ -0,0 +1,2 @@ +1.login() + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From b86fba42dc93e4a0197a97d2062305f8a352c5fc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 15:56:35 +0800 Subject: [PATCH 009/106] =?UTF-8?q?Update=20=E4=BF=AE=E6=94=B9AI.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/修改AI.md b/修改AI.md index 28c5998..e67c09b 100644 --- a/修改AI.md +++ b/修改AI.md @@ -1,2 +1,2 @@ -1.login() +1.login(): ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From f8aa8a40ce688f8a3e21f4f0e97aea9ad5e612cc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 15:58:56 +0800 Subject: [PATCH 010/106] =?UTF-8?q?Update=20=E4=BF=AE=E6=94=B9AI.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/修改AI.md b/修改AI.md index e67c09b..a21a06a 100644 --- a/修改AI.md +++ b/修改AI.md @@ -1,2 +1,2 @@ 1.login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。// \ No newline at end of file -- 2.34.1 From f9866f114c4a937615071e99fe5e6ec2cf279109 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 15:59:15 +0800 Subject: [PATCH 011/106] =?UTF-8?q?Update=20=E4=BF=AE=E6=94=B9AI.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/修改AI.md b/修改AI.md index a21a06a..7131f09 100644 --- a/修改AI.md +++ b/修改AI.md @@ -1,2 +1,2 @@ 1.login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。// \ No newline at end of file + //ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 91f7074fc88aeb05384c2f489507b363aa0375bd Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:02:18 +0800 Subject: [PATCH 012/106] =?UTF-8?q?Update=20=E4=BF=AE=E6=94=B9AI.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/修改AI.md b/修改AI.md index 7131f09..b64d067 100644 --- a/修改AI.md +++ b/修改AI.md @@ -1,2 +1,2 @@ -1.login(): - //ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file +#login(): + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From d20baa590a64df99e74bc28996887b581e0be1c2 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:34:56 +0800 Subject: [PATCH 013/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/类的设计.md b/类的设计.md index 554fc79..8ec723a 100644 --- a/类的设计.md +++ b/类的设计.md @@ -1,5 +1,5 @@ #类的设计 -##User +##User(用户实体) ###作用: 存储用户账户信息,包括用户名、密码和用户类型 ###属性: @@ -16,4 +16,20 @@ public String getPassword() public void setPassword(String password) public UserType getUserType() - public void setUserType(UserType userType) + public void setUserType(String userType) + +##UserManager(用户管理类) +###作用: + 管理用户登录状态、类型切换和用户认证 +###属性: + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 +###方法: + public boolean login(String username, String password) // 用户登录验证 + public void logout() // 用户退出登录 + public boolean switchUserType(String newType) // 切换题目难度类型 + public boolean isLoggedIn() // 检查用户是否已登录 + public User getCurrentUser() // 获取当前用户信息 + private void initializeUsers() // 初始化预设用户账户 + public UserManager() // 构造函数 -- 2.34.1 From 7712be37743cc21220b94591071afb50d41873a4 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:36:42 +0800 Subject: [PATCH 015/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/类的设计.md b/类的设计.md index 8ec723a..8c4beb9 100644 --- a/类的设计.md +++ b/类的设计.md @@ -26,10 +26,10 @@ private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 ###方法: - public boolean login(String username, String password) // 用户登录验证 - public void logout() // 用户退出登录 - public boolean switchUserType(String newType) // 切换题目难度类型 - public boolean isLoggedIn() // 检查用户是否已登录 - public User getCurrentUser() // 获取当前用户信息 - private void initializeUsers() // 初始化预设用户账户 - public UserManager() // 构造函数 + public boolean login(String username, String password) // 用户登录验证 + public void logout() // 用户退出登录 + public boolean switchUserType(String newType) // 切换题目难度类型 + public boolean isLoggedIn() // 检查用户是否已登录 + public User getCurrentUser() // 获取当前用户信息 + private void initializeUsers() // 初始化预设用户账户 + public UserManager() // 构造函数 -- 2.34.1 From af5db23e106428a3a5c67f97bad8a6b4317edf3f Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:47:54 +0800 Subject: [PATCH 016/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/类的设计.md b/类的设计.md index 8c4beb9..d142342 100644 --- a/类的设计.md +++ b/类的设计.md @@ -22,14 +22,14 @@ ###作用: 管理用户登录状态、类型切换和用户认证 ###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 ###方法: - public boolean login(String username, String password) // 用户登录验证 - public void logout() // 用户退出登录 - public boolean switchUserType(String newType) // 切换题目难度类型 - public boolean isLoggedIn() // 检查用户是否已登录 - public User getCurrentUser() // 获取当前用户信息 - private void initializeUsers() // 初始化预设用户账户 - public UserManager() // 构造函数 + public boolean login(String username, String password) // 用户登录验证 + public void logout() // 用户退出登录 + public boolean switchUserType(String newType) // 切换题目难度类型 + public boolean isLoggedIn() // 检查用户是否已登录 + public User getCurrentUser() // 获取当前用户信息 + private void initializeUsers() // 初始化预设用户账户 + public UserManager() // 构造函数 -- 2.34.1 From 58f79b23a275988a3ed4c77e1abcc5c563ab66ff Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:48:35 +0800 Subject: [PATCH 017/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 1 + 1 file changed, 1 insertion(+) diff --git a/类的设计.md b/类的设计.md index d142342..413b3a1 100644 --- a/类的设计.md +++ b/类的设计.md @@ -25,6 +25,7 @@ private Map users; // 存储所有用户信息 private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 + ###方法: public boolean login(String username, String password) // 用户登录验证 public void logout() // 用户退出登录 -- 2.34.1 From e7803348a6b5bd7c0ea6088edc13ab6681fe60cc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:51:24 +0800 Subject: [PATCH 018/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/类的设计.md b/类的设计.md index 413b3a1..f757725 100644 --- a/类的设计.md +++ b/类的设计.md @@ -22,10 +22,9 @@ ###作用: 管理用户登录状态、类型切换和用户认证 ###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 - + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 ###方法: public boolean login(String username, String password) // 用户登录验证 public void logout() // 用户退出登录 -- 2.34.1 From 4d2ec02f4de30ec197f61f8a0a58aff35467f9cb Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:55:28 +0800 Subject: [PATCH 019/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/类的设计.md b/类的设计.md index f757725..a202949 100644 --- a/类的设计.md +++ b/类的设计.md @@ -27,9 +27,9 @@ private String currentType; // 当前题目类型 ###方法: public boolean login(String username, String password) // 用户登录验证 - public void logout() // 用户退出登录 + public void logout() // 用户退出登录 public boolean switchUserType(String newType) // 切换题目难度类型 public boolean isLoggedIn() // 检查用户是否已登录 - public User getCurrentUser() // 获取当前用户信息 + public User getCurrentUser() // 获取当前用户信息 private void initializeUsers() // 初始化预设用户账户 - public UserManager() // 构造函数 + public UserManager() // 构造函数 -- 2.34.1 From de5824c81d43501bc1865cd6aea852407b8a397a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 16:57:12 +0800 Subject: [PATCH 020/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/类的设计.md b/类的设计.md index a202949..81a7bd2 100644 --- a/类的设计.md +++ b/类的设计.md @@ -26,10 +26,17 @@ private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 ###方法: - public boolean login(String username, String password) // 用户登录验证 - public void logout() // 用户退出登录 - public boolean switchUserType(String newType) // 切换题目难度类型 - public boolean isLoggedIn() // 检查用户是否已登录 - public User getCurrentUser() // 获取当前用户信息 - private void initializeUsers() // 初始化预设用户账户 - public UserManager() // 构造函数 + public boolean login(String username, String password) + // 用户登录验证 + public void logout() + // 用户退出登录 + public boolean switchUserType(String newType) + // 切换题目难度类型 + public boolean isLoggedIn() + // 检查用户是否已登录 + public User getCurrentUser() + // 获取当前用户信息 + private void initializeUsers() + // 初始化预设用户账户 + public UserManager() + // 构造函数 -- 2.34.1 From 5016858aff1e75a92ca381121ae8107e2b676c8e Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:02:31 +0800 Subject: [PATCH 021/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/类的设计.md b/类的设计.md index 81a7bd2..c3d16e8 100644 --- a/类的设计.md +++ b/类的设计.md @@ -25,7 +25,9 @@ private Map users; // 存储所有用户信息 private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 + ###方法: + ...java public boolean login(String username, String password) // 用户登录验证 public void logout() -- 2.34.1 From 1bf92c838fa50a70ad6c8dc7cbfee81bbf711299 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:05:08 +0800 Subject: [PATCH 022/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/类的设计.md b/类的设计.md index c3d16e8..768be20 100644 --- a/类的设计.md +++ b/类的设计.md @@ -27,18 +27,10 @@ private String currentType; // 当前题目类型 ###方法: - ...java public boolean login(String username, String password) - // 用户登录验证 public void logout() - // 用户退出登录 public boolean switchUserType(String newType) - // 切换题目难度类型 public boolean isLoggedIn() - // 检查用户是否已登录 public User getCurrentUser() - // 获取当前用户信息 private void initializeUsers() - // 初始化预设用户账户 public UserManager() - // 构造函数 -- 2.34.1 From a6672dcea89c23455fb3302a681500e1f128738d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:08:32 +0800 Subject: [PATCH 023/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 1 + 1 file changed, 1 insertion(+) diff --git a/类的设计.md b/类的设计.md index 768be20..0475769 100644 --- a/类的设计.md +++ b/类的设计.md @@ -22,6 +22,7 @@ ###作用: 管理用户登录状态、类型切换和用户认证 ###属性: + '''java private Map users; // 存储所有用户信息 private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 -- 2.34.1 From 69f67be6fc45b10ea6332915cfb610b403d1a301 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:09:03 +0800 Subject: [PATCH 024/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/类的设计.md b/类的设计.md index 0475769..c1a00b3 100644 --- a/类的设计.md +++ b/类的设计.md @@ -22,7 +22,7 @@ ###作用: 管理用户登录状态、类型切换和用户认证 ###属性: - '''java + ```java private Map users; // 存储所有用户信息 private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 -- 2.34.1 From a0a60c2f6bb23b3c4aeab913f8ae63d9cc16e800 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:10:27 +0800 Subject: [PATCH 025/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/类的设计.md b/类的设计.md index c1a00b3..1474c8a 100644 --- a/类的设计.md +++ b/类的设计.md @@ -26,12 +26,12 @@ private Map users; // 存储所有用户信息 private User currentUser; // 当前登录用户 private String currentType; // 当前题目类型 - + java``` ###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() + public boolean login(String username, String password) + public void logout() + public boolean switchUserType(String newType) + public boolean isLoggedIn() + public User getCurrentUser() + private void initializeUsers() + public UserManager() -- 2.34.1 From 3040d9d5edb2a9e5a284b955ee6c27a46c33e7a5 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Tue, 23 Sep 2025 17:11:23 +0800 Subject: [PATCH 026/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/类的设计.md b/类的设计.md index 1474c8a..d6dfe3a 100644 --- a/类的设计.md +++ b/类的设计.md @@ -22,11 +22,9 @@ ###作用: 管理用户登录状态、类型切换和用户认证 ###属性: - ```java - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 - java``` + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 ###方法: public boolean login(String username, String password) public void logout() -- 2.34.1 From 1cecac417307124aa2ba5bb46a1a436a4a76b359 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:37:27 +0800 Subject: [PATCH 027/106] ADD file via upload --- develop/src | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 develop/src diff --git a/develop/src b/develop/src new file mode 100644 index 0000000..e69de29 -- 2.34.1 From c3bab0fc41ceb0a8b59ee52e7e0659699358738d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:42:39 +0800 Subject: [PATCH 028/106] Delete 'develop/src' --- develop/src | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 develop/src diff --git a/develop/src b/develop/src deleted file mode 100644 index e69de29..0000000 -- 2.34.1 From 5de489e8ed42f967d5eb68138c511c3fdfc91ecf Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:44:34 +0800 Subject: [PATCH 029/106] ADD file via upload --- Google编码规范 | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Google编码规范 diff --git a/Google编码规范 b/Google编码规范 new file mode 100644 index 0000000..e69de29 -- 2.34.1 From 3553a566f01ecae351ed8a79a86c58d5c0c98ad4 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:45:22 +0800 Subject: [PATCH 030/106] =?UTF-8?q?Delete=20'Google=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E8=A7=84=E8=8C=83'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Google编码规范 | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Google编码规范 diff --git a/Google编码规范 b/Google编码规范 deleted file mode 100644 index e69de29..0000000 -- 2.34.1 From 92206bc5257113a2beff8df274a0980f25260d36 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:46:24 +0800 Subject: [PATCH 031/106] ADD file via upload --- src/Main.java | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..161f506 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,29 @@ +import java.util.Scanner; + + +//无UI界面 +//public class Main{ +// public static void main(String[] args) { +// Scanner scanner = new Scanner(System.in); +// UserManager UserManager1 = new UserManager(); +// Boolean flag = false; +// while(!flag) { +// System.out.println("请输入账号:"); +// String username = scanner.nextLine(); +// System.out.println("请输入密码:"); +// String password = scanner.nextLine(); +// if (UserManager1.login(username, password)) { +// System.out.println("登录成功"); +// flag = true; +// } +// } +// } +//} + + +//public class Main { +// public static void main(String[] args) { +// // 启动 GUI 界面 +// new UserLoginGUI(); +// } +//} \ No newline at end of file -- 2.34.1 From d2179b7048cfb1393eaeb82058bfd49763d6fa91 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:49:00 +0800 Subject: [PATCH 032/106] ADD file via upload --- doc/README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..839034f --- /dev/null +++ b/doc/README.md @@ -0,0 +1,56 @@ +# 软件需求分析 + +## 1. 引言 + +该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 + +## 2. 功能需求 + +### 2.1 用户登录功能 +- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 +- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 +- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 + +### 2.2 题目生成功能 +- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 +- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 +- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 + +### 2.3 避免重复题目 +- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 + +### 2.4 账号类型切换功能 +- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 +- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 + +### 2.5 退出功能 +- **输入**:用户输入-1以退出当前登录状态并重新登录。 + +## 3. 系统架构设计 + +### 3.1 用户登录模块 +- **输入**:用户名和密码 +- **处理**:验证用户输入,确认是否匹配预设账号 +- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 + +### 3.2 题目生成模块 +- **输入**:题目数量和账户类型 +- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 + +### 3.3 文件管理模块 +- **输入**:生成的题目 +- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 +- **输出**:生成的题目文件保存在指定的文件夹中。 + +### 3.4 账号类型切换模块 +- **输入**:切换命令“切换为 XX” +- **处理**:修改当前账号类型并更新题目生成模式。 + +### 3.5 错误处理和提示模块 +- **输入**:用户的各种操作 +- **处理**:根据不同情况给出详细的错误提示和操作提示。 + +## 4. 数据库设计 + +由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 + -- 2.34.1 From b98d95a9a0e1b76554be6924d61995916a3883bb Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:49:25 +0800 Subject: [PATCH 033/106] ADD file via upload --- src/类的设计.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/类的设计.md diff --git a/src/类的设计.md b/src/类的设计.md new file mode 100644 index 0000000..d6dfe3a --- /dev/null +++ b/src/类的设计.md @@ -0,0 +1,35 @@ +#类的设计 +##User(用户实体) +###作用: + 存储用户账户信息,包括用户名、密码和用户类型 +###属性: + private String username; // 用户名 + private String password; // 密码 + private String userType; // 用户类型(小学/初中/高中) +###方法: + public boolean validateCredentials(String inputUsername, String inputPassword) + // 验证用户名和密码是否匹配 + + // Getter和Setter方法 + public String getUsername() + public void setUsername(String username) + public String getPassword() + public void setPassword(String password) + public UserType getUserType() + public void setUserType(String userType) + +##UserManager(用户管理类) +###作用: + 管理用户登录状态、类型切换和用户认证 +###属性: + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 +###方法: + public boolean login(String username, String password) + public void logout() + public boolean switchUserType(String newType) + public boolean isLoggedIn() + public User getCurrentUser() + private void initializeUsers() + public UserManager() -- 2.34.1 From ffdcccbcecb094f731b6cd165dd19513e7efd4bc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:49:54 +0800 Subject: [PATCH 034/106] =?UTF-8?q?Delete=20'src/=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/类的设计.md | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/类的设计.md diff --git a/src/类的设计.md b/src/类的设计.md deleted file mode 100644 index d6dfe3a..0000000 --- a/src/类的设计.md +++ /dev/null @@ -1,35 +0,0 @@ -#类的设计 -##User(用户实体) -###作用: - 存储用户账户信息,包括用户名、密码和用户类型 -###属性: - private String username; // 用户名 - private String password; // 密码 - private String userType; // 用户类型(小学/初中/高中) -###方法: - public boolean validateCredentials(String inputUsername, String inputPassword) - // 验证用户名和密码是否匹配 - - // Getter和Setter方法 - public String getUsername() - public void setUsername(String username) - public String getPassword() - public void setPassword(String password) - public UserType getUserType() - public void setUserType(String userType) - -##UserManager(用户管理类) -###作用: - 管理用户登录状态、类型切换和用户认证 -###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 -###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() -- 2.34.1 From df2a9ce69988e395032a94775d495955d89c6883 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:50:38 +0800 Subject: [PATCH 035/106] ADD file via upload --- doc/类的设计.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 doc/类的设计.md diff --git a/doc/类的设计.md b/doc/类的设计.md new file mode 100644 index 0000000..d6dfe3a --- /dev/null +++ b/doc/类的设计.md @@ -0,0 +1,35 @@ +#类的设计 +##User(用户实体) +###作用: + 存储用户账户信息,包括用户名、密码和用户类型 +###属性: + private String username; // 用户名 + private String password; // 密码 + private String userType; // 用户类型(小学/初中/高中) +###方法: + public boolean validateCredentials(String inputUsername, String inputPassword) + // 验证用户名和密码是否匹配 + + // Getter和Setter方法 + public String getUsername() + public void setUsername(String username) + public String getPassword() + public void setPassword(String password) + public UserType getUserType() + public void setUserType(String userType) + +##UserManager(用户管理类) +###作用: + 管理用户登录状态、类型切换和用户认证 +###属性: + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 +###方法: + public boolean login(String username, String password) + public void logout() + public boolean switchUserType(String newType) + public boolean isLoggedIn() + public User getCurrentUser() + private void initializeUsers() + public UserManager() -- 2.34.1 From a281b708773615ca8ec262837992b543cdfd5599 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:50:58 +0800 Subject: [PATCH 036/106] ADD file via upload --- doc/修改AI.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 doc/修改AI.md diff --git a/doc/修改AI.md b/doc/修改AI.md new file mode 100644 index 0000000..b64d067 --- /dev/null +++ b/doc/修改AI.md @@ -0,0 +1,2 @@ +#login(): + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 2af060cbfc9787fd5c96b773050da06f75df4342 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:51:07 +0800 Subject: [PATCH 037/106] Delete 'README.md' --- README.md | 56 ------------------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 839034f..0000000 --- a/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# 软件需求分析 - -## 1. 引言 - -该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 - -## 2. 功能需求 - -### 2.1 用户登录功能 -- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 -- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 -- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 - -### 2.2 题目生成功能 -- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 -- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 -- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 - -### 2.3 避免重复题目 -- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 - -### 2.4 账号类型切换功能 -- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 -- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 - -### 2.5 退出功能 -- **输入**:用户输入-1以退出当前登录状态并重新登录。 - -## 3. 系统架构设计 - -### 3.1 用户登录模块 -- **输入**:用户名和密码 -- **处理**:验证用户输入,确认是否匹配预设账号 -- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 - -### 3.2 题目生成模块 -- **输入**:题目数量和账户类型 -- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 - -### 3.3 文件管理模块 -- **输入**:生成的题目 -- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 -- **输出**:生成的题目文件保存在指定的文件夹中。 - -### 3.4 账号类型切换模块 -- **输入**:切换命令“切换为 XX” -- **处理**:修改当前账号类型并更新题目生成模式。 - -### 3.5 错误处理和提示模块 -- **输入**:用户的各种操作 -- **处理**:根据不同情况给出详细的错误提示和操作提示。 - -## 4. 数据库设计 - -由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 - -- 2.34.1 From 1f751d3457fa8316775e6d9ca031b30731c68ad2 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:51:15 +0800 Subject: [PATCH 038/106] =?UTF-8?q?Delete=20'=E4=BF=AE=E6=94=B9AI.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 修改AI.md diff --git a/修改AI.md b/修改AI.md deleted file mode 100644 index b64d067..0000000 --- a/修改AI.md +++ /dev/null @@ -1,2 +0,0 @@ -#login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From d76ff6c4b1c0d5fec911906cb186800e69f46b5f Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Wed, 24 Sep 2025 23:51:22 +0800 Subject: [PATCH 039/106] =?UTF-8?q?Delete=20'=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 类的设计.md | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 类的设计.md diff --git a/类的设计.md b/类的设计.md deleted file mode 100644 index d6dfe3a..0000000 --- a/类的设计.md +++ /dev/null @@ -1,35 +0,0 @@ -#类的设计 -##User(用户实体) -###作用: - 存储用户账户信息,包括用户名、密码和用户类型 -###属性: - private String username; // 用户名 - private String password; // 密码 - private String userType; // 用户类型(小学/初中/高中) -###方法: - public boolean validateCredentials(String inputUsername, String inputPassword) - // 验证用户名和密码是否匹配 - - // Getter和Setter方法 - public String getUsername() - public void setUsername(String username) - public String getPassword() - public void setPassword(String password) - public UserType getUserType() - public void setUserType(String userType) - -##UserManager(用户管理类) -###作用: - 管理用户登录状态、类型切换和用户认证 -###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 -###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() -- 2.34.1 From 3e1bb4b1390d0a54929c22b5afdd2f8280027084 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:02:10 +0800 Subject: [PATCH 040/106] Delete 'src/Main.java' --- src/Main.java | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 161f506..0000000 --- a/src/Main.java +++ /dev/null @@ -1,29 +0,0 @@ -import java.util.Scanner; - - -//无UI界面 -//public class Main{ -// public static void main(String[] args) { -// Scanner scanner = new Scanner(System.in); -// UserManager UserManager1 = new UserManager(); -// Boolean flag = false; -// while(!flag) { -// System.out.println("请输入账号:"); -// String username = scanner.nextLine(); -// System.out.println("请输入密码:"); -// String password = scanner.nextLine(); -// if (UserManager1.login(username, password)) { -// System.out.println("登录成功"); -// flag = true; -// } -// } -// } -//} - - -//public class Main { -// public static void main(String[] args) { -// // 启动 GUI 界面 -// new UserLoginGUI(); -// } -//} \ No newline at end of file -- 2.34.1 From 9dbb0b74764b577758f984f7560154e70a5dace2 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:02:48 +0800 Subject: [PATCH 041/106] ADD file via upload --- src/Expr.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/Expr.java diff --git a/src/Expr.java b/src/Expr.java new file mode 100644 index 0000000..2b2130b --- /dev/null +++ b/src/Expr.java @@ -0,0 +1,10 @@ +public class Expr { + String expression; + int value; + String mainOperator; + public Expr(String expression,int value,String mainOperator){ + this.expression = expression; + this.mainOperator = mainOperator; + this.value = value; + } +} -- 2.34.1 From df7326ffe3b9cab272f6b9c4625a7bf2837a4f04 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:00 +0800 Subject: [PATCH 042/106] ADD file via upload --- src/AbstractQuestionSeting.java | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/AbstractQuestionSeting.java diff --git a/src/AbstractQuestionSeting.java b/src/AbstractQuestionSeting.java new file mode 100644 index 0000000..2eef642 --- /dev/null +++ b/src/AbstractQuestionSeting.java @@ -0,0 +1,46 @@ +import java.util.Random; + +public abstract class AbstractQuestionSeting implements QuestionSeting{ + static Random rand = new Random(); + + public String getRandOpe(){ + String[] operators= {"+","-","*","/"}; + int index = rand.nextInt(4); + return operators[index]; + } + public String getRandnum(){ + int num = rand.nextInt(1,100); + return String.valueOf(num); + } + // 定义运算符优先级 + public int getPriority(String op) { + if (op == null) return -1; // 叶子节点(数字) + if (op.equals("+") || op.equals("-")) return 1; + if (op.equals("*") || op.equals("/")) return 2; + return 0; + } + + public String addParenthesesIfNeeded(Expr child, String parentOp, boolean isRightChild) { + if (child.mainOperator == null) { + return child.expression; // 纯数字不用括号 + } + + int parentPriority = getPriority(parentOp); + int childPriority = getPriority(child.mainOperator); + + // 子优先级 < 父优先级 → 必须加括号 + if (childPriority < parentPriority) { + return "(" + child.expression + ")"; + } + + // 特殊情况: + // 右子树如果是 "-" 或 "/",即使同级也要加括号 + if (isRightChild && (parentOp.equals("-") || parentOp.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.expression + ")"; + } + } + + return child.expression; // 其他情况不用括号 + } +} -- 2.34.1 From dc7f5742b278a5074648aefab83827ec75facfe6 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:12 +0800 Subject: [PATCH 043/106] ADD file via upload --- src/AllSystem.java | 133 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/AllSystem.java diff --git a/src/AllSystem.java b/src/AllSystem.java new file mode 100644 index 0000000..3c7a24d --- /dev/null +++ b/src/AllSystem.java @@ -0,0 +1,133 @@ +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class AllSystem { + public Scanner scanner; + public UserManager userManager; + public FileManager fileManager; + public QueSetingFactory queSetingFactory; + public QuestionSeting questionSeting; + public String tip = ""; + + public void initial(){ + this.scanner = new Scanner(System.in,"GBK"); + userManager = new UserManager(); + fileManager = new FileManager(); + queSetingFactory= new QueSetingFactory(); + questionSeting = null; + } + + public void home() throws IOException { + initial(); + System.out.println("*********欢迎来到试卷生成系统*********"); + System.out.println("请输入账号和密码(中间用空格分开):"); + boolean flag = false; + while (!flag) { + String input = scanner.nextLine(); + String[] inputs = input.split(" "); + if (inputs.length!=2){ + System.out.println("您的输入不符合要求,请重试"); + continue; + } + if (userManager.login(inputs[0], inputs[1])) { + flag = true; + } + } + setpaper(); + } + + public void setpaper() throws IOException { + clearScreen(); + System.out.println("准备生成 " + userManager.getCurrentUser().getUserType()+" 数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); + this.questionSeting = queSetingFactory.getQueSeting(userManager.getCurrentUser().getUserType()); + String input = scanner.nextLine(); + firsthandle(input); + } + + public void firsthandle(String input) throws IOException { + boolean flag = true; + while(flag) { + try { + int count = Integer.parseInt(input); + if (count == -1) { + flag = false; + home(); + } else if (10 <= count && count <= 30) { + List ques = new ArrayList<>(); + int i = count; + while (i > 0) { + String que = questionSeting.setQuestion(3).expression; + if (fileManager.checkQuestion(que, userManager.getCurrentUser())) { + ques.add(que); + i--; + } + } + fileManager.savePaper(userManager.getCurrentUser(), ques); + tip = "试卷生成成功,"; + flag = false; + choose(); + + } else { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + }catch (NumberFormatException e) { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + } + } + + public void choose() throws IOException { + clearScreen(); + System.out.println("*********欢迎光临,"+userManager.getCurrentUser().getUsername()+"*********"); + System.out.println("0. 退出(输入0)"); + System.out.println("1. 生成试卷(输入1)"); + System.out.println("2. 切换类型(输入:切换为XX)(XX为“初中”,“小学”,“高中”)"); + System.out.println(tip+"请选择接下来操作:"); + String input = scanner.nextLine(); + secondHandle(input); + choose(); + } + + public void secondHandle(String input) throws IOException { + if(input.equals("0")){ + home(); + } + else if(input.equals("1")){ + setpaper(); + } + else if(input.length()>=4 && input.startsWith("切换为")) { + String time = input.substring(3); + tip = "切换成功,"; + if (time.equals("小学")){ + questionSeting = queSetingFactory.getQueSeting("小学"); + } else if(time.equals("初中")) { + questionSeting = queSetingFactory.getQueSeting("初中"); + } else if(time.equals("高中")) { + questionSeting = queSetingFactory.getQueSeting("高中"); + }else{ + System.out.println("输入不符合要求,请重试"); + input = scanner.nextLine(); + secondHandle(input); + } + } + else{ + System.out.println("输入不符合要求,请重试"); + input = scanner.nextLine(); + secondHandle(input); + } + } + + public static void clearScreen() { + try { + // Windows 下执行 cls + new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); + } catch (IOException | InterruptedException e) { + + e.printStackTrace(); + } + } +} -- 2.34.1 From aa1f49a397f84647f3c05dc4d4b386b983963123 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:26 +0800 Subject: [PATCH 044/106] ADD file via upload --- src/FileManager.java | 81 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/FileManager.java diff --git a/src/FileManager.java b/src/FileManager.java new file mode 100644 index 0000000..7e1af26 --- /dev/null +++ b/src/FileManager.java @@ -0,0 +1,81 @@ +import java.io.File; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +public class FileManager { + public static String rootpath = "./试卷/"; + + public void savePaper(User user, List questions) throws IOException { + // 创建用户目录 + String userDir = rootpath + user.getUsername(); + Path userPath = Paths.get(userDir); + if (!Files.exists(userPath)) { + Files.createDirectories(userPath); + } + + // 生成文件名 + String filename = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt"; + Path filePath = userPath.resolve(filename); + // 写入文件 + try (PrintWriter writer = new PrintWriter(new FileWriter(filePath.toFile(), StandardCharsets.UTF_8))) { + for (int i = 0; i < questions.size(); i++) { + writer.printf("%d. %s%n%n", i + 1, questions.get(i)); + } + } + } + + public boolean checkQuestion(String que,User user) throws IOException { + String userDir = rootpath + user.getUsername(); + Path userPath = Paths.get(userDir); + if (!Files.exists(userPath)) { + return true; + } + else{ + File dir = new File("./试卷/"+user.getUsername()); + File[] files = dir.listFiles(); // 获取目录下的所有文件/文件夹 + for (File f : files) { + for(String line : Files.readAllLines(f.toPath())){ + if(!line.isEmpty()){ + line = line.replaceFirst("^\\d+\\.\\s*", ""); + if(line.equals(que)){ + System.out.println("有道一样的题"); + return false; + } + } + }; + } + } + return true; + } + + +// public static void main(String[] args) throws IOException { +// FileManager file = new FileManager(); +// User fanwen = new User("fan","111","初中"); +// PrimaryQueSeting queSeting = new PrimaryQueSeting(); +// List questions = new ArrayList<>(); +// //questions.add("26 / 24 * 29 / 37 + 36 * 45 + 21 * 33"); +// for (int i = 9; i <10 ; i++) { +// String que = "26 / 24 * 29 / 37 + 36 * 45 + 21 * 33"; +// //String que = queSeting.setQuestion(3); +// if(file.checkQuestion(que,fanwen)) +// questions.add(que); +// } +// try { +// file.savePaper(fanwen,questions); +// } catch (IOException e) { +// System.out.println("试卷存储异常"); +// } +// } + + +} -- 2.34.1 From 6f45a715628ddc4c6661ae45328dff93ef48930f Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:37 +0800 Subject: [PATCH 045/106] ADD file via upload --- src/HighQueSeting.java | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/HighQueSeting.java diff --git a/src/HighQueSeting.java b/src/HighQueSeting.java new file mode 100644 index 0000000..f2116bc --- /dev/null +++ b/src/HighQueSeting.java @@ -0,0 +1,37 @@ +public class HighQueSeting extends AbstractQuestionSeting{ + + @Override + public Expr setQuestion(int count) { + if (count == 1) { + String expr = getRandnum(); + return new Expr(expr,Integer.parseInt(expr),null); + } + int leftCount = 1 + rand.nextInt(count - 1); + int rightCount = count - leftCount; + Expr left = setQuestion(leftCount); + Expr right = setQuestion(rightCount); + String op = getRandOpe(); + while(op.equals("/") && right.value == 0) { + right = setQuestion(rightCount); + } + if (op.equals("-") && left.value < right.value) { + Expr temp = left; + left = right; + right = temp; + } + // 给左右两边加括号(如果需要) + String leftExpr = addParenthesesIfNeeded(left, op, false); + String rightExpr = addParenthesesIfNeeded(right, op, true); + + // 计算值 + int value = 0; + switch (op) { + case "+": value = left.value + right.value; break; + case "-": value = left.value - right.value; break; + case "*": value = left.value * right.value; break; + case "/": value = left.value / right.value; break; + } + + return new Expr(leftExpr + " " + op + " " + rightExpr, value, op); + } +} -- 2.34.1 From 2728edb6e18284351cea300c2c87f0558557682b Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:49 +0800 Subject: [PATCH 046/106] ADD file via upload --- src/Main.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..955e79f --- /dev/null +++ b/src/Main.java @@ -0,0 +1,13 @@ +import java.io.IOException; +import java.util.Scanner; + +public class Main{ + public static void main(String[] args){ + AllSystem allSystem = new AllSystem(); + try { + allSystem.home(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} -- 2.34.1 From 82cf70272fbcb8dda14a3d59a7ad757071086744 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:03:58 +0800 Subject: [PATCH 047/106] ADD file via upload --- src/MiddleQueSeting.java | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/MiddleQueSeting.java diff --git a/src/MiddleQueSeting.java b/src/MiddleQueSeting.java new file mode 100644 index 0000000..b7da279 --- /dev/null +++ b/src/MiddleQueSeting.java @@ -0,0 +1,112 @@ +public class MiddleQueSeting extends AbstractQuestionSeting{ + // 重写优先级方法,支持新运算符 + @Override + public int getPriority(String op) { + if (op == null) return -1; // 叶子节点(数字) + if (op.equals("²") || op.equals("√")) return 3; // 平方和开根号优先级最高 + if (op.equals("+") || op.equals("-")) return 1; + if (op.equals("*") || op.equals("/")) return 2; + return 0; + } + + public Expr applyUnary(Expr child, String op) { + switch (op) { + case "²": + if (child.mainOperator == null) { + return new Expr(child.expression + "²", child.value * child.value, "²"); + } + return new Expr("(" + child.expression + ")²", child.value * child.value, "²"); + case "√": + if (child.value < 0) { // 负数不能开根号 + String numStr = getRandnum(); + child = new Expr(numStr,Integer.parseInt(numStr), null); + } + if (child.mainOperator == null) { + return new Expr("√" + child.expression, child.value * child.value, "√"); + } + return new Expr("√(" + child.expression + ")", (int) Math.sqrt(child.value), "√"); + default: + return child; + } + } + // 重写父类的括号添加方法,支持平方和开根号 + @Override + public String addParenthesesIfNeeded(Expr child, String parentOp, boolean isRightChild) { + if (child.mainOperator == null || child.mainOperator.equals("²") || child.mainOperator.equals("√")) { + return child.expression; // 数字、平方、开根号不用括号 + } + + int parentPriority = getPriority(parentOp); + int childPriority = getPriority(child.mainOperator); + + // 子优先级 < 父优先级 → 必须加括号 + if (childPriority < parentPriority) { + return "(" + child.expression + ")"; + } + + // 特殊情况:右子树如果是 "-" 或 "/",即使同级也要加括号 + if (isRightChild && (parentOp.equals("-") || parentOp.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.expression + ")"; + } + } + + return child.expression; + } + + @Override + public Expr setQuestion(int count){ + Expr result = firstsetQuestion(count); + if(!result.expression.contains("²") && !result.expression.contains("√")){ + result = firstsetQuestion(count); + } + return result; + } + + public Expr firstsetQuestion(int count) { + if (count == 1) { + String numStr = getRandnum(); + int num = Integer.parseInt(numStr); + Expr expr = new Expr(numStr, num, null); + expr = probability(expr); + return expr; + } + + int leftCount = 1 + rand.nextInt(count - 1); + int rightCount = count - leftCount; + + Expr left = firstsetQuestion(leftCount); + Expr right = firstsetQuestion(rightCount); + + String op = getRandOpe(); + double value = 0; + switch (op) { + case "+": value = left.value + right.value; break; + case "-": + value = left.value - right.value; break; + case "*": value = left.value * right.value; break; + case "/": + if (right.value == 0) return firstsetQuestion(count); + value = left.value / right.value; break; + } + + String leftExpr = addParenthesesIfNeeded(left, op, false); + String rightExpr = addParenthesesIfNeeded(right, op, true); + + Expr result = new Expr(leftExpr + " " + op + " " + rightExpr, (int) value, op); + + result = probability(result); + return result; + } + + public Expr probability(Expr result){ + if (rand.nextDouble() < 0.3) { + String[] unaryOps = {"²", "√"}; + String unaryOp = unaryOps[rand.nextInt(unaryOps.length)]; + result = applyUnary(result, unaryOp); + result.mainOperator = unaryOp; + } + return result; + } +} + -- 2.34.1 From d693f77a80cb3f1b094feb36056bc319b2fab47a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:04:09 +0800 Subject: [PATCH 048/106] ADD file via upload --- src/PrimaryQueSeting.java | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/PrimaryQueSeting.java diff --git a/src/PrimaryQueSeting.java b/src/PrimaryQueSeting.java new file mode 100644 index 0000000..7a745d8 --- /dev/null +++ b/src/PrimaryQueSeting.java @@ -0,0 +1,42 @@ +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.util.Arrays; +import java.util.Random; + +public class PrimaryQueSeting extends AbstractQuestionSeting{ + @Override + public Expr setQuestion(int count) { + if (count == 1) { + String expr = getRandnum(); + return new Expr(expr,Integer.parseInt(expr),null); + } + int leftCount = 1 + rand.nextInt(count - 1); + int rightCount = count - leftCount; + Expr left = setQuestion(leftCount); + Expr right = setQuestion(rightCount); + String op = getRandOpe(); + while(op.equals("/") && right.value == 0) { + right = setQuestion(rightCount); + } + if (op.equals("-") && left.value < right.value) { + Expr temp = left; + left = right; + right = temp; + } + // 给左右两边加括号(如果需要) + String leftExpr = addParenthesesIfNeeded(left, op, false); + String rightExpr = addParenthesesIfNeeded(right, op, true); + + // 计算值 + int value = 0; + switch (op) { + case "+": value = left.value + right.value; break; + case "-": value = left.value - right.value; break; + case "*": value = left.value * right.value; break; + case "/": value = left.value / right.value; break; + } + + return new Expr(leftExpr + " " + op + " " + rightExpr, value, op); + } +} -- 2.34.1 From 77ac53bbbeaebe615fbea694aad3dc4af8f33e2d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:04:18 +0800 Subject: [PATCH 049/106] ADD file via upload --- src/QueSetingFactory.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/QueSetingFactory.java diff --git a/src/QueSetingFactory.java b/src/QueSetingFactory.java new file mode 100644 index 0000000..ce95ab7 --- /dev/null +++ b/src/QueSetingFactory.java @@ -0,0 +1,19 @@ +public class QueSetingFactory { + public QuestionSeting getQueSeting(String type){ + switch (type) { + case "小学" -> { + return new PrimaryQueSeting(); + } + case "初中" -> { + return new MiddleQueSeting(); + } + case "高中" -> { + return new HighQueSeting(); + } + default -> { + System.out.println("类型错误"); + return null; + } + } + } +} -- 2.34.1 From 29d61590df2dbc5b468842ed09bac822865cc437 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:04:36 +0800 Subject: [PATCH 050/106] ADD file via upload --- src/QuestionSeting.java | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/QuestionSeting.java diff --git a/src/QuestionSeting.java b/src/QuestionSeting.java new file mode 100644 index 0000000..0d58a97 --- /dev/null +++ b/src/QuestionSeting.java @@ -0,0 +1,3 @@ +public interface QuestionSeting { + Expr setQuestion(int count); +} -- 2.34.1 From 953679bd61d55dc83f42bdb353c9c45f160d290b Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:04:46 +0800 Subject: [PATCH 051/106] ADD file via upload --- src/User.java | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/User.java diff --git a/src/User.java b/src/User.java new file mode 100644 index 0000000..00671f8 --- /dev/null +++ b/src/User.java @@ -0,0 +1,36 @@ +public class User { + private String username; // 用户名 + private String password; // 密码 + private String userType; //(小学/初中/高中) + + public String getUsername(){ + return username; + } + + public void setUsername(String username){ + this.username = username; + } + public String getPassword(){ + return password; + } + public void setPassword(String password){ + this.password = password; + } + public String getUserType(){ + return userType; + } + public void setUserType(String userType){ + this.userType = userType; + } + + public boolean validateCredentials(String inputUsername, String inputPassword) { + // 验证用户名和密码是否匹配 + return this.username.equals(inputUsername) && this.password.equals(inputPassword); + } + + public User(String username,String password,String userType){ + this.username = username; + this.password = password; + this.userType = userType; + } +} -- 2.34.1 From 73c15fbf239879b5bd5e281de701e8d8a8bc61bf Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:04:58 +0800 Subject: [PATCH 052/106] ADD file via upload --- src/UserManager.java | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/UserManager.java diff --git a/src/UserManager.java b/src/UserManager.java new file mode 100644 index 0000000..1ee3d23 --- /dev/null +++ b/src/UserManager.java @@ -0,0 +1,74 @@ +import java.util.HashMap; +import java.util.Map; + +public class UserManager { + private Map users = new HashMap<>(); // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 + + public boolean login(String username, String password) { + // 检查用户是否存在且密码正确 + if (users.containsKey(username)) { + User user = users.get(username); + if (user.validateCredentials(username, password)) { + currentUser = user; + currentType = user.getUserType(); + System.out.println("登录成功"); + return true; + } + else{ + System.out.println("密码错误,请重试"); + } + } + else{ + System.out.println("该账号不存在,请重试"); + } + return false; + } + + public void logout() { + //用户退出 + currentUser = null; + currentType = null; + } + + public boolean switchUserType(String newType) { + //切换用户的出题类型 + if (currentUser != null) { + currentType = newType; + return true; + } + return false; + } + + public boolean isLoggedIn() { + // 检查用户是否已登录 + return currentUser != null; + } + + public User getCurrentUser() { + //获取当前用户信息 + return currentUser; + } + + private void initializeUsers() { + // 初始化预设账户 + + users.put("张三1", new User("张三1", "123", "小学")); + users.put("张三2", new User("张三2", "123", "小学")); + users.put("张三3", new User("张三3", "123", "小学")); + users.put("李四1", new User("李四1", "123", "初中")); + users.put("李四2", new User("李四2", "123", "初中")); + users.put("李四3", new User("李四3", "123", "初中")); + users.put("王五1", new User("王五1", "123", "高中")); + users.put("王五2", new User("王五2", "123", "高中")); + users.put("王五3", new User("王五3", "123", "高中")); + } + + public UserManager(){ + //构造函数初始化 + initializeUsers(); + } +} + + -- 2.34.1 From a99b23df2ae675acd4b3e1faf10958caa056232a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:09:49 +0800 Subject: [PATCH 053/106] Delete 'doc/README.md' --- doc/README.md | 56 --------------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 839034f..0000000 --- a/doc/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# 软件需求分析 - -## 1. 引言 - -该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 - -## 2. 功能需求 - -### 2.1 用户登录功能 -- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 -- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 -- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 - -### 2.2 题目生成功能 -- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 -- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 -- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 - -### 2.3 避免重复题目 -- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 - -### 2.4 账号类型切换功能 -- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 -- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 - -### 2.5 退出功能 -- **输入**:用户输入-1以退出当前登录状态并重新登录。 - -## 3. 系统架构设计 - -### 3.1 用户登录模块 -- **输入**:用户名和密码 -- **处理**:验证用户输入,确认是否匹配预设账号 -- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 - -### 3.2 题目生成模块 -- **输入**:题目数量和账户类型 -- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 - -### 3.3 文件管理模块 -- **输入**:生成的题目 -- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 -- **输出**:生成的题目文件保存在指定的文件夹中。 - -### 3.4 账号类型切换模块 -- **输入**:切换命令“切换为 XX” -- **处理**:修改当前账号类型并更新题目生成模式。 - -### 3.5 错误处理和提示模块 -- **输入**:用户的各种操作 -- **处理**:根据不同情况给出详细的错误提示和操作提示。 - -## 4. 数据库设计 - -由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 - -- 2.34.1 From 125e4a45f6d6784498d62bc1b9dafd8e643c82ac Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:10:07 +0800 Subject: [PATCH 054/106] =?UTF-8?q?Delete=20'doc/=E4=BF=AE=E6=94=B9AI.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/修改AI.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 doc/修改AI.md diff --git a/doc/修改AI.md b/doc/修改AI.md deleted file mode 100644 index b64d067..0000000 --- a/doc/修改AI.md +++ /dev/null @@ -1,2 +0,0 @@ -#login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 76859f50a551778fa2b6c2c34fa8f49cd524c0e6 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 01:10:14 +0800 Subject: [PATCH 055/106] =?UTF-8?q?Delete=20'doc/=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/类的设计.md | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 doc/类的设计.md diff --git a/doc/类的设计.md b/doc/类的设计.md deleted file mode 100644 index d6dfe3a..0000000 --- a/doc/类的设计.md +++ /dev/null @@ -1,35 +0,0 @@ -#类的设计 -##User(用户实体) -###作用: - 存储用户账户信息,包括用户名、密码和用户类型 -###属性: - private String username; // 用户名 - private String password; // 密码 - private String userType; // 用户类型(小学/初中/高中) -###方法: - public boolean validateCredentials(String inputUsername, String inputPassword) - // 验证用户名和密码是否匹配 - - // Getter和Setter方法 - public String getUsername() - public void setUsername(String username) - public String getPassword() - public void setPassword(String password) - public UserType getUserType() - public void setUserType(String userType) - -##UserManager(用户管理类) -###作用: - 管理用户登录状态、类型切换和用户认证 -###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 -###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() -- 2.34.1 From 23b3e62e5c04c8e2ecc1b8ef365c5431a0399a63 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 11:21:19 +0800 Subject: [PATCH 056/106] ADD file via upload --- doc/README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..839034f --- /dev/null +++ b/doc/README.md @@ -0,0 +1,56 @@ +# 软件需求分析 + +## 1. 引言 + +该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 + +## 2. 功能需求 + +### 2.1 用户登录功能 +- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 +- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 +- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 + +### 2.2 题目生成功能 +- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 +- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 +- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 + +### 2.3 避免重复题目 +- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 + +### 2.4 账号类型切换功能 +- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 +- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 + +### 2.5 退出功能 +- **输入**:用户输入-1以退出当前登录状态并重新登录。 + +## 3. 系统架构设计 + +### 3.1 用户登录模块 +- **输入**:用户名和密码 +- **处理**:验证用户输入,确认是否匹配预设账号 +- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 + +### 3.2 题目生成模块 +- **输入**:题目数量和账户类型 +- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 + +### 3.3 文件管理模块 +- **输入**:生成的题目 +- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 +- **输出**:生成的题目文件保存在指定的文件夹中。 + +### 3.4 账号类型切换模块 +- **输入**:切换命令“切换为 XX” +- **处理**:修改当前账号类型并更新题目生成模式。 + +### 3.5 错误处理和提示模块 +- **输入**:用户的各种操作 +- **处理**:根据不同情况给出详细的错误提示和操作提示。 + +## 4. 数据库设计 + +由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 + -- 2.34.1 From 3ed9df715f21a96009fd1cb3158893001416300e Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 11:21:32 +0800 Subject: [PATCH 057/106] ADD file via upload --- doc/类的设计.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 doc/类的设计.md diff --git a/doc/类的设计.md b/doc/类的设计.md new file mode 100644 index 0000000..d6dfe3a --- /dev/null +++ b/doc/类的设计.md @@ -0,0 +1,35 @@ +#类的设计 +##User(用户实体) +###作用: + 存储用户账户信息,包括用户名、密码和用户类型 +###属性: + private String username; // 用户名 + private String password; // 密码 + private String userType; // 用户类型(小学/初中/高中) +###方法: + public boolean validateCredentials(String inputUsername, String inputPassword) + // 验证用户名和密码是否匹配 + + // Getter和Setter方法 + public String getUsername() + public void setUsername(String username) + public String getPassword() + public void setPassword(String password) + public UserType getUserType() + public void setUserType(String userType) + +##UserManager(用户管理类) +###作用: + 管理用户登录状态、类型切换和用户认证 +###属性: + private Map users; // 存储所有用户信息 + private User currentUser; // 当前登录用户 + private String currentType; // 当前题目类型 +###方法: + public boolean login(String username, String password) + public void logout() + public boolean switchUserType(String newType) + public boolean isLoggedIn() + public User getCurrentUser() + private void initializeUsers() + public UserManager() -- 2.34.1 From 77d7084b5d71574cfd9a356d0e1ce3049f491018 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 11:21:41 +0800 Subject: [PATCH 058/106] ADD file via upload --- 修改AI.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 修改AI.md diff --git a/修改AI.md b/修改AI.md new file mode 100644 index 0000000..b64d067 --- /dev/null +++ b/修改AI.md @@ -0,0 +1,2 @@ +#login(): + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 3384be2546bab811be1dc2c4719c4790cad26d17 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 11:21:56 +0800 Subject: [PATCH 059/106] =?UTF-8?q?Delete=20'=E4=BF=AE=E6=94=B9AI.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 修改AI.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 修改AI.md diff --git a/修改AI.md b/修改AI.md deleted file mode 100644 index b64d067..0000000 --- a/修改AI.md +++ /dev/null @@ -1,2 +0,0 @@ -#login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 6af816c48a36382202e81dc32b3d6e4e9ef79847 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Sun, 28 Sep 2025 11:22:10 +0800 Subject: [PATCH 060/106] ADD file via upload --- doc/修改AI.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 doc/修改AI.md diff --git a/doc/修改AI.md b/doc/修改AI.md new file mode 100644 index 0000000..b64d067 --- /dev/null +++ b/doc/修改AI.md @@ -0,0 +1,2 @@ +#login(): + ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From 34070e2c0ac499d74999405dd923be42cbccb2e4 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:54:49 +0800 Subject: [PATCH 061/106] ADD file via upload --- src/AbstractQuestionSetting.java | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/AbstractQuestionSetting.java diff --git a/src/AbstractQuestionSetting.java b/src/AbstractQuestionSetting.java new file mode 100644 index 0000000..5b29b43 --- /dev/null +++ b/src/AbstractQuestionSetting.java @@ -0,0 +1,55 @@ +// AbstractQuestionSetting.java +import java.util.Random; + +public abstract class AbstractQuestionSetting implements QuestionSetting { + protected static final Random RANDOM = new Random(); + + public String getRandomOperator() { + String[] operators = {"+", "-", "*", "/"}; + int index = RANDOM.nextInt(4); + return operators[index]; + } + + public String getRandomNumber() { + int number = RANDOM.nextInt(1, 100); + return String.valueOf(number); + } + + public int getPriority(String operator) { + if (operator == null) { + return -1; + } + if (operator.equals("²") || operator.equals("√") + || operator.equals("sin") || operator.equals("cos") || operator.equals("tan")) { + return 3; + } + if (operator.equals("+") || operator.equals("-")) { + return 1; + } + if (operator.equals("*") || operator.equals("/")) { + return 2; + } + return 0; + } + + public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { + if (child.getMainOperator() == null) { + return child.getExpression(); + } + + int parentPriority = getPriority(parentOperator); + int childPriority = getPriority(child.getMainOperator()); + + if (childPriority < parentPriority) { + return "(" + child.getExpression() + ")"; + } + + if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.getExpression() + ")"; + } + } + + return child.getExpression(); + } +} \ No newline at end of file -- 2.34.1 From 343b4b4ef639e76aa5a4b238ffcc7d2885cff66f Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:55:27 +0800 Subject: [PATCH 062/106] Delete 'src/AbstractQuestionSeting.java' --- src/AbstractQuestionSeting.java | 46 --------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 src/AbstractQuestionSeting.java diff --git a/src/AbstractQuestionSeting.java b/src/AbstractQuestionSeting.java deleted file mode 100644 index 2eef642..0000000 --- a/src/AbstractQuestionSeting.java +++ /dev/null @@ -1,46 +0,0 @@ -import java.util.Random; - -public abstract class AbstractQuestionSeting implements QuestionSeting{ - static Random rand = new Random(); - - public String getRandOpe(){ - String[] operators= {"+","-","*","/"}; - int index = rand.nextInt(4); - return operators[index]; - } - public String getRandnum(){ - int num = rand.nextInt(1,100); - return String.valueOf(num); - } - // 定义运算符优先级 - public int getPriority(String op) { - if (op == null) return -1; // 叶子节点(数字) - if (op.equals("+") || op.equals("-")) return 1; - if (op.equals("*") || op.equals("/")) return 2; - return 0; - } - - public String addParenthesesIfNeeded(Expr child, String parentOp, boolean isRightChild) { - if (child.mainOperator == null) { - return child.expression; // 纯数字不用括号 - } - - int parentPriority = getPriority(parentOp); - int childPriority = getPriority(child.mainOperator); - - // 子优先级 < 父优先级 → 必须加括号 - if (childPriority < parentPriority) { - return "(" + child.expression + ")"; - } - - // 特殊情况: - // 右子树如果是 "-" 或 "/",即使同级也要加括号 - if (isRightChild && (parentOp.equals("-") || parentOp.equals("/"))) { - if (parentPriority == childPriority) { - return "(" + child.expression + ")"; - } - } - - return child.expression; // 其他情况不用括号 - } -} -- 2.34.1 From 23bca4113d51c4d6b3e7fb32de50f6bd59633155 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:55:37 +0800 Subject: [PATCH 063/106] Delete 'src/AllSystem.java' --- src/AllSystem.java | 133 --------------------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 src/AllSystem.java diff --git a/src/AllSystem.java b/src/AllSystem.java deleted file mode 100644 index 3c7a24d..0000000 --- a/src/AllSystem.java +++ /dev/null @@ -1,133 +0,0 @@ -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -public class AllSystem { - public Scanner scanner; - public UserManager userManager; - public FileManager fileManager; - public QueSetingFactory queSetingFactory; - public QuestionSeting questionSeting; - public String tip = ""; - - public void initial(){ - this.scanner = new Scanner(System.in,"GBK"); - userManager = new UserManager(); - fileManager = new FileManager(); - queSetingFactory= new QueSetingFactory(); - questionSeting = null; - } - - public void home() throws IOException { - initial(); - System.out.println("*********欢迎来到试卷生成系统*********"); - System.out.println("请输入账号和密码(中间用空格分开):"); - boolean flag = false; - while (!flag) { - String input = scanner.nextLine(); - String[] inputs = input.split(" "); - if (inputs.length!=2){ - System.out.println("您的输入不符合要求,请重试"); - continue; - } - if (userManager.login(inputs[0], inputs[1])) { - flag = true; - } - } - setpaper(); - } - - public void setpaper() throws IOException { - clearScreen(); - System.out.println("准备生成 " + userManager.getCurrentUser().getUserType()+" 数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); - this.questionSeting = queSetingFactory.getQueSeting(userManager.getCurrentUser().getUserType()); - String input = scanner.nextLine(); - firsthandle(input); - } - - public void firsthandle(String input) throws IOException { - boolean flag = true; - while(flag) { - try { - int count = Integer.parseInt(input); - if (count == -1) { - flag = false; - home(); - } else if (10 <= count && count <= 30) { - List ques = new ArrayList<>(); - int i = count; - while (i > 0) { - String que = questionSeting.setQuestion(3).expression; - if (fileManager.checkQuestion(que, userManager.getCurrentUser())) { - ques.add(que); - i--; - } - } - fileManager.savePaper(userManager.getCurrentUser(), ques); - tip = "试卷生成成功,"; - flag = false; - choose(); - - } else { - System.out.println("您的输入不符合要求,请重试"); - input = scanner.nextLine(); - } - }catch (NumberFormatException e) { - System.out.println("您的输入不符合要求,请重试"); - input = scanner.nextLine(); - } - } - } - - public void choose() throws IOException { - clearScreen(); - System.out.println("*********欢迎光临,"+userManager.getCurrentUser().getUsername()+"*********"); - System.out.println("0. 退出(输入0)"); - System.out.println("1. 生成试卷(输入1)"); - System.out.println("2. 切换类型(输入:切换为XX)(XX为“初中”,“小学”,“高中”)"); - System.out.println(tip+"请选择接下来操作:"); - String input = scanner.nextLine(); - secondHandle(input); - choose(); - } - - public void secondHandle(String input) throws IOException { - if(input.equals("0")){ - home(); - } - else if(input.equals("1")){ - setpaper(); - } - else if(input.length()>=4 && input.startsWith("切换为")) { - String time = input.substring(3); - tip = "切换成功,"; - if (time.equals("小学")){ - questionSeting = queSetingFactory.getQueSeting("小学"); - } else if(time.equals("初中")) { - questionSeting = queSetingFactory.getQueSeting("初中"); - } else if(time.equals("高中")) { - questionSeting = queSetingFactory.getQueSeting("高中"); - }else{ - System.out.println("输入不符合要求,请重试"); - input = scanner.nextLine(); - secondHandle(input); - } - } - else{ - System.out.println("输入不符合要求,请重试"); - input = scanner.nextLine(); - secondHandle(input); - } - } - - public static void clearScreen() { - try { - // Windows 下执行 cls - new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); - } catch (IOException | InterruptedException e) { - - e.printStackTrace(); - } - } -} -- 2.34.1 From 070bf94cdfbe9b199d8f7341fd0df73b0f409e4e Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:55:46 +0800 Subject: [PATCH 064/106] Delete 'src/Expr.java' --- src/Expr.java | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/Expr.java diff --git a/src/Expr.java b/src/Expr.java deleted file mode 100644 index 2b2130b..0000000 --- a/src/Expr.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Expr { - String expression; - int value; - String mainOperator; - public Expr(String expression,int value,String mainOperator){ - this.expression = expression; - this.mainOperator = mainOperator; - this.value = value; - } -} -- 2.34.1 From bc5bd95aae41b3d55545c332a537baa8b0800121 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:55:53 +0800 Subject: [PATCH 065/106] Delete 'src/FileManager.java' --- src/FileManager.java | 81 -------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 src/FileManager.java diff --git a/src/FileManager.java b/src/FileManager.java deleted file mode 100644 index 7e1af26..0000000 --- a/src/FileManager.java +++ /dev/null @@ -1,81 +0,0 @@ -import java.io.File; -import java.io.PrintWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; - -public class FileManager { - public static String rootpath = "./试卷/"; - - public void savePaper(User user, List questions) throws IOException { - // 创建用户目录 - String userDir = rootpath + user.getUsername(); - Path userPath = Paths.get(userDir); - if (!Files.exists(userPath)) { - Files.createDirectories(userPath); - } - - // 生成文件名 - String filename = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt"; - Path filePath = userPath.resolve(filename); - // 写入文件 - try (PrintWriter writer = new PrintWriter(new FileWriter(filePath.toFile(), StandardCharsets.UTF_8))) { - for (int i = 0; i < questions.size(); i++) { - writer.printf("%d. %s%n%n", i + 1, questions.get(i)); - } - } - } - - public boolean checkQuestion(String que,User user) throws IOException { - String userDir = rootpath + user.getUsername(); - Path userPath = Paths.get(userDir); - if (!Files.exists(userPath)) { - return true; - } - else{ - File dir = new File("./试卷/"+user.getUsername()); - File[] files = dir.listFiles(); // 获取目录下的所有文件/文件夹 - for (File f : files) { - for(String line : Files.readAllLines(f.toPath())){ - if(!line.isEmpty()){ - line = line.replaceFirst("^\\d+\\.\\s*", ""); - if(line.equals(que)){ - System.out.println("有道一样的题"); - return false; - } - } - }; - } - } - return true; - } - - -// public static void main(String[] args) throws IOException { -// FileManager file = new FileManager(); -// User fanwen = new User("fan","111","初中"); -// PrimaryQueSeting queSeting = new PrimaryQueSeting(); -// List questions = new ArrayList<>(); -// //questions.add("26 / 24 * 29 / 37 + 36 * 45 + 21 * 33"); -// for (int i = 9; i <10 ; i++) { -// String que = "26 / 24 * 29 / 37 + 36 * 45 + 21 * 33"; -// //String que = queSeting.setQuestion(3); -// if(file.checkQuestion(que,fanwen)) -// questions.add(que); -// } -// try { -// file.savePaper(fanwen,questions); -// } catch (IOException e) { -// System.out.println("试卷存储异常"); -// } -// } - - -} -- 2.34.1 From 786659278d511b1e20781ee94ad9f3d91544889d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:55:58 +0800 Subject: [PATCH 066/106] Delete 'src/HighQueSeting.java' --- src/HighQueSeting.java | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 src/HighQueSeting.java diff --git a/src/HighQueSeting.java b/src/HighQueSeting.java deleted file mode 100644 index f2116bc..0000000 --- a/src/HighQueSeting.java +++ /dev/null @@ -1,37 +0,0 @@ -public class HighQueSeting extends AbstractQuestionSeting{ - - @Override - public Expr setQuestion(int count) { - if (count == 1) { - String expr = getRandnum(); - return new Expr(expr,Integer.parseInt(expr),null); - } - int leftCount = 1 + rand.nextInt(count - 1); - int rightCount = count - leftCount; - Expr left = setQuestion(leftCount); - Expr right = setQuestion(rightCount); - String op = getRandOpe(); - while(op.equals("/") && right.value == 0) { - right = setQuestion(rightCount); - } - if (op.equals("-") && left.value < right.value) { - Expr temp = left; - left = right; - right = temp; - } - // 给左右两边加括号(如果需要) - String leftExpr = addParenthesesIfNeeded(left, op, false); - String rightExpr = addParenthesesIfNeeded(right, op, true); - - // 计算值 - int value = 0; - switch (op) { - case "+": value = left.value + right.value; break; - case "-": value = left.value - right.value; break; - case "*": value = left.value * right.value; break; - case "/": value = left.value / right.value; break; - } - - return new Expr(leftExpr + " " + op + " " + rightExpr, value, op); - } -} -- 2.34.1 From 7e1702475dda26063118c65379cc6b6bc654e94a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:06 +0800 Subject: [PATCH 067/106] Delete 'src/Main.java' --- src/Main.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 955e79f..0000000 --- a/src/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -import java.io.IOException; -import java.util.Scanner; - -public class Main{ - public static void main(String[] args){ - AllSystem allSystem = new AllSystem(); - try { - allSystem.home(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} -- 2.34.1 From c4576845523dcdd4b57117b59b5548e7e410a571 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:13 +0800 Subject: [PATCH 068/106] Delete 'src/MiddleQueSeting.java' --- src/MiddleQueSeting.java | 112 --------------------------------------- 1 file changed, 112 deletions(-) delete mode 100644 src/MiddleQueSeting.java diff --git a/src/MiddleQueSeting.java b/src/MiddleQueSeting.java deleted file mode 100644 index b7da279..0000000 --- a/src/MiddleQueSeting.java +++ /dev/null @@ -1,112 +0,0 @@ -public class MiddleQueSeting extends AbstractQuestionSeting{ - // 重写优先级方法,支持新运算符 - @Override - public int getPriority(String op) { - if (op == null) return -1; // 叶子节点(数字) - if (op.equals("²") || op.equals("√")) return 3; // 平方和开根号优先级最高 - if (op.equals("+") || op.equals("-")) return 1; - if (op.equals("*") || op.equals("/")) return 2; - return 0; - } - - public Expr applyUnary(Expr child, String op) { - switch (op) { - case "²": - if (child.mainOperator == null) { - return new Expr(child.expression + "²", child.value * child.value, "²"); - } - return new Expr("(" + child.expression + ")²", child.value * child.value, "²"); - case "√": - if (child.value < 0) { // 负数不能开根号 - String numStr = getRandnum(); - child = new Expr(numStr,Integer.parseInt(numStr), null); - } - if (child.mainOperator == null) { - return new Expr("√" + child.expression, child.value * child.value, "√"); - } - return new Expr("√(" + child.expression + ")", (int) Math.sqrt(child.value), "√"); - default: - return child; - } - } - // 重写父类的括号添加方法,支持平方和开根号 - @Override - public String addParenthesesIfNeeded(Expr child, String parentOp, boolean isRightChild) { - if (child.mainOperator == null || child.mainOperator.equals("²") || child.mainOperator.equals("√")) { - return child.expression; // 数字、平方、开根号不用括号 - } - - int parentPriority = getPriority(parentOp); - int childPriority = getPriority(child.mainOperator); - - // 子优先级 < 父优先级 → 必须加括号 - if (childPriority < parentPriority) { - return "(" + child.expression + ")"; - } - - // 特殊情况:右子树如果是 "-" 或 "/",即使同级也要加括号 - if (isRightChild && (parentOp.equals("-") || parentOp.equals("/"))) { - if (parentPriority == childPriority) { - return "(" + child.expression + ")"; - } - } - - return child.expression; - } - - @Override - public Expr setQuestion(int count){ - Expr result = firstsetQuestion(count); - if(!result.expression.contains("²") && !result.expression.contains("√")){ - result = firstsetQuestion(count); - } - return result; - } - - public Expr firstsetQuestion(int count) { - if (count == 1) { - String numStr = getRandnum(); - int num = Integer.parseInt(numStr); - Expr expr = new Expr(numStr, num, null); - expr = probability(expr); - return expr; - } - - int leftCount = 1 + rand.nextInt(count - 1); - int rightCount = count - leftCount; - - Expr left = firstsetQuestion(leftCount); - Expr right = firstsetQuestion(rightCount); - - String op = getRandOpe(); - double value = 0; - switch (op) { - case "+": value = left.value + right.value; break; - case "-": - value = left.value - right.value; break; - case "*": value = left.value * right.value; break; - case "/": - if (right.value == 0) return firstsetQuestion(count); - value = left.value / right.value; break; - } - - String leftExpr = addParenthesesIfNeeded(left, op, false); - String rightExpr = addParenthesesIfNeeded(right, op, true); - - Expr result = new Expr(leftExpr + " " + op + " " + rightExpr, (int) value, op); - - result = probability(result); - return result; - } - - public Expr probability(Expr result){ - if (rand.nextDouble() < 0.3) { - String[] unaryOps = {"²", "√"}; - String unaryOp = unaryOps[rand.nextInt(unaryOps.length)]; - result = applyUnary(result, unaryOp); - result.mainOperator = unaryOp; - } - return result; - } -} - -- 2.34.1 From 461709ffcd5a2dba3ba6841689073fbe16ad4c42 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:20 +0800 Subject: [PATCH 069/106] Delete 'src/PrimaryQueSeting.java' --- src/PrimaryQueSeting.java | 42 --------------------------------------- 1 file changed, 42 deletions(-) delete mode 100644 src/PrimaryQueSeting.java diff --git a/src/PrimaryQueSeting.java b/src/PrimaryQueSeting.java deleted file mode 100644 index 7a745d8..0000000 --- a/src/PrimaryQueSeting.java +++ /dev/null @@ -1,42 +0,0 @@ -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import java.util.Arrays; -import java.util.Random; - -public class PrimaryQueSeting extends AbstractQuestionSeting{ - @Override - public Expr setQuestion(int count) { - if (count == 1) { - String expr = getRandnum(); - return new Expr(expr,Integer.parseInt(expr),null); - } - int leftCount = 1 + rand.nextInt(count - 1); - int rightCount = count - leftCount; - Expr left = setQuestion(leftCount); - Expr right = setQuestion(rightCount); - String op = getRandOpe(); - while(op.equals("/") && right.value == 0) { - right = setQuestion(rightCount); - } - if (op.equals("-") && left.value < right.value) { - Expr temp = left; - left = right; - right = temp; - } - // 给左右两边加括号(如果需要) - String leftExpr = addParenthesesIfNeeded(left, op, false); - String rightExpr = addParenthesesIfNeeded(right, op, true); - - // 计算值 - int value = 0; - switch (op) { - case "+": value = left.value + right.value; break; - case "-": value = left.value - right.value; break; - case "*": value = left.value * right.value; break; - case "/": value = left.value / right.value; break; - } - - return new Expr(leftExpr + " " + op + " " + rightExpr, value, op); - } -} -- 2.34.1 From c1ec2735caf9a9d4a924e63a1803122d451fc1ed Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:26 +0800 Subject: [PATCH 070/106] Delete 'src/QueSetingFactory.java' --- src/QueSetingFactory.java | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 src/QueSetingFactory.java diff --git a/src/QueSetingFactory.java b/src/QueSetingFactory.java deleted file mode 100644 index ce95ab7..0000000 --- a/src/QueSetingFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -public class QueSetingFactory { - public QuestionSeting getQueSeting(String type){ - switch (type) { - case "小学" -> { - return new PrimaryQueSeting(); - } - case "初中" -> { - return new MiddleQueSeting(); - } - case "高中" -> { - return new HighQueSeting(); - } - default -> { - System.out.println("类型错误"); - return null; - } - } - } -} -- 2.34.1 From e059e3832827ed075cc372d2b9691cbb713d6e64 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:31 +0800 Subject: [PATCH 071/106] Delete 'src/QuestionSeting.java' --- src/QuestionSeting.java | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/QuestionSeting.java diff --git a/src/QuestionSeting.java b/src/QuestionSeting.java deleted file mode 100644 index 0d58a97..0000000 --- a/src/QuestionSeting.java +++ /dev/null @@ -1,3 +0,0 @@ -public interface QuestionSeting { - Expr setQuestion(int count); -} -- 2.34.1 From 9e08f4eb74c23c49ad6524618998f0e012b5f73c Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:37 +0800 Subject: [PATCH 072/106] Delete 'src/User.java' --- src/User.java | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 src/User.java diff --git a/src/User.java b/src/User.java deleted file mode 100644 index 00671f8..0000000 --- a/src/User.java +++ /dev/null @@ -1,36 +0,0 @@ -public class User { - private String username; // 用户名 - private String password; // 密码 - private String userType; //(小学/初中/高中) - - public String getUsername(){ - return username; - } - - public void setUsername(String username){ - this.username = username; - } - public String getPassword(){ - return password; - } - public void setPassword(String password){ - this.password = password; - } - public String getUserType(){ - return userType; - } - public void setUserType(String userType){ - this.userType = userType; - } - - public boolean validateCredentials(String inputUsername, String inputPassword) { - // 验证用户名和密码是否匹配 - return this.username.equals(inputUsername) && this.password.equals(inputPassword); - } - - public User(String username,String password,String userType){ - this.username = username; - this.password = password; - this.userType = userType; - } -} -- 2.34.1 From 84d7b43c4da003e6ce80fde043a44d42c3bbd2b5 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:56:44 +0800 Subject: [PATCH 073/106] Delete 'src/UserManager.java' --- src/UserManager.java | 74 -------------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 src/UserManager.java diff --git a/src/UserManager.java b/src/UserManager.java deleted file mode 100644 index 1ee3d23..0000000 --- a/src/UserManager.java +++ /dev/null @@ -1,74 +0,0 @@ -import java.util.HashMap; -import java.util.Map; - -public class UserManager { - private Map users = new HashMap<>(); // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 - - public boolean login(String username, String password) { - // 检查用户是否存在且密码正确 - if (users.containsKey(username)) { - User user = users.get(username); - if (user.validateCredentials(username, password)) { - currentUser = user; - currentType = user.getUserType(); - System.out.println("登录成功"); - return true; - } - else{ - System.out.println("密码错误,请重试"); - } - } - else{ - System.out.println("该账号不存在,请重试"); - } - return false; - } - - public void logout() { - //用户退出 - currentUser = null; - currentType = null; - } - - public boolean switchUserType(String newType) { - //切换用户的出题类型 - if (currentUser != null) { - currentType = newType; - return true; - } - return false; - } - - public boolean isLoggedIn() { - // 检查用户是否已登录 - return currentUser != null; - } - - public User getCurrentUser() { - //获取当前用户信息 - return currentUser; - } - - private void initializeUsers() { - // 初始化预设账户 - - users.put("张三1", new User("张三1", "123", "小学")); - users.put("张三2", new User("张三2", "123", "小学")); - users.put("张三3", new User("张三3", "123", "小学")); - users.put("李四1", new User("李四1", "123", "初中")); - users.put("李四2", new User("李四2", "123", "初中")); - users.put("李四3", new User("李四3", "123", "初中")); - users.put("王五1", new User("王五1", "123", "高中")); - users.put("王五2", new User("王五2", "123", "高中")); - users.put("王五3", new User("王五3", "123", "高中")); - } - - public UserManager(){ - //构造函数初始化 - initializeUsers(); - } -} - - -- 2.34.1 From 16782b15f1238785a9aba71921a9d689e8e1080e Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:57:22 +0800 Subject: [PATCH 074/106] ADD file via upload --- src/AllSystem.java | 162 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/AllSystem.java diff --git a/src/AllSystem.java b/src/AllSystem.java new file mode 100644 index 0000000..d4b2278 --- /dev/null +++ b/src/AllSystem.java @@ -0,0 +1,162 @@ +// AllSystem.java +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class AllSystem { + private static final String EXIT_COMMAND = "exit"; + private static final String SWITCH_PREFIX = "切换为"; + + private Scanner scanner; + private UserManager userManager; + private FileManager fileManager; + private QuestionSettingFactory questionSettingFactory; + private QuestionSetting questionSetting; + private String tipMessage = ""; + private String currentMode = ""; + private boolean isFirstLogin = true; + + public static void clearScreen() { + try { + new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); + } catch (IOException | InterruptedException exception) { + exception.printStackTrace(); + } + } + + public void initialize() { + this.scanner = new Scanner(System.in); + userManager = new UserManager(); + fileManager = new FileManager(); + questionSettingFactory = new QuestionSettingFactory(); + questionSetting = null; + } + + public void showHomeMenu() throws IOException { + initialize(); + clearScreen(); + System.out.println("**************欢迎来到试卷生成系统**************"); + System.out.println("————————————————————————————————————————————————"); + System.out.println("请输入账号和密码(中间用空格分开,输入exit退出):"); + boolean loginSuccessful = false; + while (!loginSuccessful) { + String input = scanner.nextLine(); + if (input.isEmpty()) { + System.out.println("您的输入不符合要求,请重试"); + continue; + } + if (input.equals(EXIT_COMMAND)) { + System.exit(0); + } + String[] inputs = input.split(" "); + if (inputs.length != 2) { + System.out.println("您的输入不符合要求,请重试"); + continue; + } + if (userManager.login(inputs[0], inputs[1])) { + loginSuccessful = true; + } + } + currentMode = userManager.getCurrentUser().getUserType(); + this.questionSetting = questionSettingFactory.getQuestionSetting( + userManager.getCurrentUser().getUserType()); + setPaper(); + } + + public void setPaper() throws IOException { + clearScreen(); + if (isFirstLogin) { + System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); + isFirstLogin = false; + } else { + System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量"); + } + String input = scanner.nextLine(); + handleFirstInput(input); + } + + public void handleFirstInput(String input) throws IOException { + boolean continueProcessing = true; + while (continueProcessing) { + try { + int questionCount = Integer.parseInt(input); + if (questionCount == -1) { + continueProcessing = false; + showHomeMenu(); + } else if (10 <= questionCount && questionCount <= 30) { + List questions = new ArrayList<>(); + int remainingQuestions = questionCount; + while (remainingQuestions > 0) { + String question = questionSetting.setQuestion(3).getExpression(); + if (fileManager.checkQuestion(question, userManager.getCurrentUser())) { + questions.add(question); + System.out.println(questionCount - remainingQuestions + 1 + ". " + question); + System.out.println(); + remainingQuestions--; + } + } + fileManager.savePaper(userManager.getCurrentUser(), questions); + tipMessage = "试卷生成成功,"; + continueProcessing = false; + System.out.println("试卷生成完成!按回车键返回主菜单..."); + scanner.nextLine(); + showChoiceMenu(); + } else { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + } catch (NumberFormatException exception) { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + } + } + + public void showChoiceMenu() throws IOException { + boolean running = true; + while (running) { + clearScreen(); + System.out.println("****************欢迎光临," + userManager.getCurrentUser().getUsername() + + "****************"); + System.out.println("————————————————————————————————————————————————"); + System.out.println("当前模式是: " + currentMode); + System.out.println("0. 退出(输入0)"); + System.out.println("1. 生成试卷(输入1)"); + System.out.println("2. 切换类型(输入:切换为XX)(XX为\"初中\",\"小学\",\"高中\")"); + System.out.println(tipMessage + "请选择接下来操作:"); + + String input = scanner.nextLine(); + running = handleSecondInput(input); + } + } + + public boolean handleSecondInput(String input) throws IOException { + if (input.equals("0")) { + clearScreen(); + showHomeMenu(); + return false; + } else if (input.equals("1")) { + clearScreen(); + setPaper(); + return true; + } else if (input.length() >= 4 && input.startsWith(SWITCH_PREFIX)) { + String type = input.substring(3); + tipMessage = "切换成功,"; + if (type.equals("小学") || type.equals("初中") || type.equals("高中")) { + questionSetting = questionSettingFactory.getQuestionSetting(type); + currentMode = type; + setPaper(); + return true; + } else { + System.out.println("请输入小学、初中和高中三个选项中的一个,请按回车重试"); + scanner.nextLine(); + return true; + } + } else { + System.out.println("输入不符合要求,请按回车重试"); + scanner.nextLine(); + return true; + } + } +} \ No newline at end of file -- 2.34.1 From c22cba424e41ed6a1295bc863d1a51088229ef19 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:57:57 +0800 Subject: [PATCH 075/106] ADD file via upload --- src/Expression.java | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/Expression.java diff --git a/src/Expression.java b/src/Expression.java new file mode 100644 index 0000000..7b130a7 --- /dev/null +++ b/src/Expression.java @@ -0,0 +1,36 @@ +// Expression.java +public class Expression { + private String expression; + private int value; + private String mainOperator; + + public Expression(String expression, int value, String mainOperator) { + this.expression = expression; + this.value = value; + this.mainOperator = mainOperator; + } + + public String getExpression() { + return expression; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getMainOperator() { + return mainOperator; + } + + public void setMainOperator(String mainOperator) { + this.mainOperator = mainOperator; + } +} \ No newline at end of file -- 2.34.1 From b28e2578faf753f81bf5aba90ef9f52858a4e3db Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:58:17 +0800 Subject: [PATCH 076/106] ADD file via upload --- FileManager.java | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 FileManager.java diff --git a/FileManager.java b/FileManager.java new file mode 100644 index 0000000..2238d16 --- /dev/null +++ b/FileManager.java @@ -0,0 +1,57 @@ +// FileManager.java +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +public class FileManager { + public static final String ROOT_PATH = "./试卷/"; + + public void savePaper(User user, List questions) throws IOException { + String userDirectory = ROOT_PATH + user.getUsername(); + Path userPath = Paths.get(userDirectory); + if (!Files.exists(userPath)) { + Files.createDirectories(userPath); + } + + String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt"; + Path filePath = userPath.resolve(fileName); + try (PrintWriter writer = new PrintWriter(new FileWriter(filePath.toFile(), StandardCharsets.UTF_8))) { + for (int index = 0; index < questions.size(); index++) { + writer.printf("%d. %s%n%n", index + 1, questions.get(index)); + } + } + } + + public boolean checkQuestion(String question, User user) throws IOException { + String userDirectory = ROOT_PATH + user.getUsername(); + Path userPath = Paths.get(userDirectory); + if (!Files.exists(userPath)) { + return true; + } else { + File directory = new File("./试卷/" + user.getUsername()); + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + for (String line : Files.readAllLines(file.toPath())) { + if (!line.isEmpty()) { + line = line.replaceFirst("^\\d+\\.\\s*", ""); + if (line.equals(question)) { + System.out.println("有道一样的题"); + return false; + } + } + } + } + } + } + return true; + } +} \ No newline at end of file -- 2.34.1 From 4fa65df42ab7e4d80c8ba8a087a83cafddb24614 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:58:23 +0800 Subject: [PATCH 077/106] Delete 'FileManager.java' --- FileManager.java | 57 ------------------------------------------------ 1 file changed, 57 deletions(-) delete mode 100644 FileManager.java diff --git a/FileManager.java b/FileManager.java deleted file mode 100644 index 2238d16..0000000 --- a/FileManager.java +++ /dev/null @@ -1,57 +0,0 @@ -// FileManager.java -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; - -public class FileManager { - public static final String ROOT_PATH = "./试卷/"; - - public void savePaper(User user, List questions) throws IOException { - String userDirectory = ROOT_PATH + user.getUsername(); - Path userPath = Paths.get(userDirectory); - if (!Files.exists(userPath)) { - Files.createDirectories(userPath); - } - - String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt"; - Path filePath = userPath.resolve(fileName); - try (PrintWriter writer = new PrintWriter(new FileWriter(filePath.toFile(), StandardCharsets.UTF_8))) { - for (int index = 0; index < questions.size(); index++) { - writer.printf("%d. %s%n%n", index + 1, questions.get(index)); - } - } - } - - public boolean checkQuestion(String question, User user) throws IOException { - String userDirectory = ROOT_PATH + user.getUsername(); - Path userPath = Paths.get(userDirectory); - if (!Files.exists(userPath)) { - return true; - } else { - File directory = new File("./试卷/" + user.getUsername()); - File[] files = directory.listFiles(); - if (files != null) { - for (File file : files) { - for (String line : Files.readAllLines(file.toPath())) { - if (!line.isEmpty()) { - line = line.replaceFirst("^\\d+\\.\\s*", ""); - if (line.equals(question)) { - System.out.println("有道一样的题"); - return false; - } - } - } - } - } - } - return true; - } -} \ No newline at end of file -- 2.34.1 From e83e431691623ebc05a72d68de86fc6f874129b1 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:58:38 +0800 Subject: [PATCH 078/106] ADD file via upload --- src/FileManager.java | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/FileManager.java diff --git a/src/FileManager.java b/src/FileManager.java new file mode 100644 index 0000000..2238d16 --- /dev/null +++ b/src/FileManager.java @@ -0,0 +1,57 @@ +// FileManager.java +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +public class FileManager { + public static final String ROOT_PATH = "./试卷/"; + + public void savePaper(User user, List questions) throws IOException { + String userDirectory = ROOT_PATH + user.getUsername(); + Path userPath = Paths.get(userDirectory); + if (!Files.exists(userPath)) { + Files.createDirectories(userPath); + } + + String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt"; + Path filePath = userPath.resolve(fileName); + try (PrintWriter writer = new PrintWriter(new FileWriter(filePath.toFile(), StandardCharsets.UTF_8))) { + for (int index = 0; index < questions.size(); index++) { + writer.printf("%d. %s%n%n", index + 1, questions.get(index)); + } + } + } + + public boolean checkQuestion(String question, User user) throws IOException { + String userDirectory = ROOT_PATH + user.getUsername(); + Path userPath = Paths.get(userDirectory); + if (!Files.exists(userPath)) { + return true; + } else { + File directory = new File("./试卷/" + user.getUsername()); + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + for (String line : Files.readAllLines(file.toPath())) { + if (!line.isEmpty()) { + line = line.replaceFirst("^\\d+\\.\\s*", ""); + if (line.equals(question)) { + System.out.println("有道一样的题"); + return false; + } + } + } + } + } + } + return true; + } +} \ No newline at end of file -- 2.34.1 From 72bede6791ca7a4a071177427faf9f5a49fc0540 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:58:55 +0800 Subject: [PATCH 079/106] ADD file via upload --- src/HighQuestionSetting.java | 126 +++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/HighQuestionSetting.java diff --git a/src/HighQuestionSetting.java b/src/HighQuestionSetting.java new file mode 100644 index 0000000..bd37cb8 --- /dev/null +++ b/src/HighQuestionSetting.java @@ -0,0 +1,126 @@ +// HighQuestionSetting.java +public class HighQuestionSetting extends AbstractQuestionSetting { + + @Override + public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { + if (child.getMainOperator() == null + || child.getMainOperator().equals("²") || child.getMainOperator().equals("√") + || child.getMainOperator().equals("sin") || child.getMainOperator().equals("cos") + || child.getMainOperator().equals("tan")) { + return child.getExpression(); + } + + int parentPriority = getPriority(parentOperator); + int childPriority = getPriority(child.getMainOperator()); + + if (childPriority < parentPriority) { + return "(" + child.getExpression() + ")"; + } + + if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.getExpression() + ")"; + } + } + + return child.getExpression(); + } + + public Expression applyUnaryOperator(Expression child, String operator) { + switch (operator) { + case "²": + if (child.getMainOperator() == null) { + return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); + } + return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); + case "√": + if (child.getValue() < 0) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + if (child.getMainOperator() == null) { + return new Expression("√" + child.getExpression(), (int) Math.sqrt(child.getValue()), "√"); + } + return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); + case "sin": + return new Expression("sin(" + child.getExpression() + ")", + (int) Math.round(Math.sin(Math.toRadians(child.getValue()))), "sin"); + case "cos": + return new Expression("cos(" + child.getExpression() + ")", + (int) Math.round(Math.cos(Math.toRadians(child.getValue()))), "cos"); + case "tan": + while (child.getValue() % 180 == 90) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + return new Expression("tan(" + child.getExpression() + ")", + (int) Math.round(Math.tan(Math.toRadians(child.getValue()))), "tan"); + default: + return child; + } + } + + @Override + public Expression setQuestion(int count) { + Expression result = generateFirstQuestion(count); + while (!result.getExpression().contains("sin") && !result.getExpression().contains("cos") + && !result.getExpression().contains("tan")) { + result = generateFirstQuestion(count); + } + return result; + } + + public Expression applyProbability(Expression result) { + if (RANDOM.nextDouble() < 0.3) { + String[] unaryOperators = {"²", "√", "sin", "cos", "tan"}; + String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; + result = applyUnaryOperator(result, unaryOperator); + result.setMainOperator(unaryOperator); + } + return result; + } + + public Expression generateFirstQuestion(int count) { + if (count == 1) { + String numberString = getRandomNumber(); + int number = Integer.parseInt(numberString); + Expression expression = new Expression(numberString, number, null); + expression = applyProbability(expression); + return expression; + } + + int leftCount = 1 + RANDOM.nextInt(count - 1); + int rightCount = count - leftCount; + + Expression left = generateFirstQuestion(leftCount); + Expression right = generateFirstQuestion(rightCount); + + String operator = getRandomOperator(); + int value = 0; + switch (operator) { + case "+": + value = left.getValue() + right.getValue(); + break; + case "-": + value = left.getValue() - right.getValue(); + break; + case "*": + value = left.getValue() * right.getValue(); + break; + case "/": + if (right.getValue() == 0) { + return generateFirstQuestion(count); + } + value = left.getValue() / right.getValue(); + break; + } + + String leftExpression = addParenthesesIfNeeded(left, operator, false); + String rightExpression = addParenthesesIfNeeded(right, operator, true); + + Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, (int) value, operator); + + result = applyProbability(result); + return result; + } +} \ No newline at end of file -- 2.34.1 From 81ba92f8ecce3614d328063034197a142a7f7566 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:59:04 +0800 Subject: [PATCH 080/106] ADD file via upload --- Main.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Main.java diff --git a/Main.java b/Main.java new file mode 100644 index 0000000..5f799d8 --- /dev/null +++ b/Main.java @@ -0,0 +1,13 @@ +import java.io.IOException; + +public class Main { + + public static void main(String[] args) { + AllSystem allSystem = new AllSystem(); + try { + allSystem.showHomeMenu(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} -- 2.34.1 From 4534eab6924721f18e099f926677c2af164acfe6 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 00:59:14 +0800 Subject: [PATCH 081/106] Delete 'Main.java' --- Main.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 Main.java diff --git a/Main.java b/Main.java deleted file mode 100644 index 5f799d8..0000000 --- a/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -import java.io.IOException; - -public class Main { - - public static void main(String[] args) { - AllSystem allSystem = new AllSystem(); - try { - allSystem.showHomeMenu(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} -- 2.34.1 From eb040a82c6dd144286ff018d0abf84eb0d584542 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:00:29 +0800 Subject: [PATCH 082/106] ADD file via upload --- src/Main.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Main.java diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..5f799d8 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,13 @@ +import java.io.IOException; + +public class Main { + + public static void main(String[] args) { + AllSystem allSystem = new AllSystem(); + try { + allSystem.showHomeMenu(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} -- 2.34.1 From e5f64f33a33f664f0c9b2711fc2eaab96318a078 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:00:39 +0800 Subject: [PATCH 083/106] ADD file via upload --- src/MiddleQuestionSetting.java | 109 +++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/MiddleQuestionSetting.java diff --git a/src/MiddleQuestionSetting.java b/src/MiddleQuestionSetting.java new file mode 100644 index 0000000..5bde507 --- /dev/null +++ b/src/MiddleQuestionSetting.java @@ -0,0 +1,109 @@ +// MiddleQuestionSetting.java +public class MiddleQuestionSetting extends AbstractQuestionSetting { + + public Expression applyUnaryOperator(Expression child, String operator) { + switch (operator) { + case "²": + if (child.getMainOperator() == null) { + return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); + } + return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); + case "√": + if (child.getValue() < 0) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + if (child.getMainOperator() == null) { + return new Expression("√" + child.getExpression(), child.getValue() * child.getValue(), "√"); + } + return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); + default: + return child; + } + } + + @Override + public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { + if (child.getMainOperator() == null || child.getMainOperator().equals("²") || child.getMainOperator().equals("√")) { + return child.getExpression(); + } + + int parentPriority = getPriority(parentOperator); + int childPriority = getPriority(child.getMainOperator()); + + if (childPriority < parentPriority) { + return "(" + child.getExpression() + ")"; + } + + if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.getExpression() + ")"; + } + } + + return child.getExpression(); + } + + @Override + public Expression setQuestion(int count) { + Expression result = generateFirstQuestion(count); + while (!result.getExpression().contains("²") && !result.getExpression().contains("√")) { + result = generateFirstQuestion(count); + } + return result; + } + + public Expression generateFirstQuestion(int count) { + if (count == 1) { + String numberString = getRandomNumber(); + int number = Integer.parseInt(numberString); + Expression expression = new Expression(numberString, number, null); + expression = applyProbability(expression); + return expression; + } + + int leftCount = 1 + RANDOM.nextInt(count - 1); + int rightCount = count - leftCount; + + Expression left = generateFirstQuestion(leftCount); + Expression right = generateFirstQuestion(rightCount); + + String operator = getRandomOperator(); + int value = 0; + switch (operator) { + case "+": + value = left.getValue() + right.getValue(); + break; + case "-": + value = left.getValue() - right.getValue(); + break; + case "*": + value = left.getValue() * right.getValue(); + break; + case "/": + while (right.getValue() == 0) { + right = generateFirstQuestion(count); + } + value = left.getValue() / right.getValue(); + break; + } + + String leftExpression = addParenthesesIfNeeded(left, operator, false); + String rightExpression = addParenthesesIfNeeded(right, operator, true); + + Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, value, operator); + + result = applyProbability(result); + return result; + } + + public Expression applyProbability(Expression result) { + if (RANDOM.nextDouble() < 0.3) { + String[] unaryOperators = {"²", "√"}; + String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; + result = applyUnaryOperator(result, unaryOperator); + result.setMainOperator(unaryOperator); + } + return result; + } +} \ No newline at end of file -- 2.34.1 From 7f30b3f4e1b38e6b84c76af9cd731b82687da8e6 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:00:49 +0800 Subject: [PATCH 084/106] ADD file via upload --- src/PrimaryQuestionSetting.java | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/PrimaryQuestionSetting.java diff --git a/src/PrimaryQuestionSetting.java b/src/PrimaryQuestionSetting.java new file mode 100644 index 0000000..72b5cd5 --- /dev/null +++ b/src/PrimaryQuestionSetting.java @@ -0,0 +1,37 @@ +// PrimaryQuestionSetting.java +public class PrimaryQuestionSetting extends AbstractQuestionSetting { + + @Override + public Expression setQuestion(int count) { + if (count == 1) { + String expression = getRandomNumber(); + return new Expression(expression, Integer.parseInt(expression), null); + } + int leftCount = 1 + RANDOM.nextInt(count - 1); + int rightCount = count - leftCount; + Expression left = setQuestion(leftCount); + Expression right = setQuestion(rightCount); + String operator = getRandomOperator(); + while (operator.equals("/") && right.getValue() == 0) { + right = setQuestion(rightCount); + } + if (operator.equals("-") && left.getValue() < right.getValue()) { + Expression temporary = left; + left = right; + right = temporary; + } + + String leftExpression = addParenthesesIfNeeded(left, operator, false); + String rightExpression = addParenthesesIfNeeded(right, operator, true); + + int value = switch (operator) { + case "+" -> left.getValue() + right.getValue(); + case "-" -> left.getValue() - right.getValue(); + case "*" -> left.getValue() * right.getValue(); + case "/" -> left.getValue() / right.getValue(); + default -> 0; + }; + + return new Expression(leftExpression + " " + operator + " " + rightExpression, value, operator); + } +} \ No newline at end of file -- 2.34.1 From b63ff78ec780c6298b39ef665ee3d322a1a79e0d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:00:58 +0800 Subject: [PATCH 085/106] ADD file via upload --- QuestionSetting.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 QuestionSetting.java diff --git a/QuestionSetting.java b/QuestionSetting.java new file mode 100644 index 0000000..db95619 --- /dev/null +++ b/QuestionSetting.java @@ -0,0 +1,4 @@ +public interface QuestionSetting { + + Expression setQuestion(int count); +} -- 2.34.1 From defd3208f77302136c38fa72043c091d2caad3e9 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:01:04 +0800 Subject: [PATCH 086/106] Delete 'QuestionSetting.java' --- QuestionSetting.java | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 QuestionSetting.java diff --git a/QuestionSetting.java b/QuestionSetting.java deleted file mode 100644 index db95619..0000000 --- a/QuestionSetting.java +++ /dev/null @@ -1,4 +0,0 @@ -public interface QuestionSetting { - - Expression setQuestion(int count); -} -- 2.34.1 From 71f3e323edd63ff97234aec76d2edc16771d076a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:01:20 +0800 Subject: [PATCH 087/106] ADD file via upload --- src/QuestionSetting.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/QuestionSetting.java diff --git a/src/QuestionSetting.java b/src/QuestionSetting.java new file mode 100644 index 0000000..db95619 --- /dev/null +++ b/src/QuestionSetting.java @@ -0,0 +1,4 @@ +public interface QuestionSetting { + + Expression setQuestion(int count); +} -- 2.34.1 From fd7d4ca5c8dc9773c44b47c78424df6e72e917a7 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:01:30 +0800 Subject: [PATCH 088/106] ADD file via upload --- src/QuestionSettingFactory.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/QuestionSettingFactory.java diff --git a/src/QuestionSettingFactory.java b/src/QuestionSettingFactory.java new file mode 100644 index 0000000..97e68c4 --- /dev/null +++ b/src/QuestionSettingFactory.java @@ -0,0 +1,20 @@ +public class QuestionSettingFactory { + + public QuestionSetting getQuestionSetting(String type) { + switch (type) { + case "小学" -> { + return new PrimaryQuestionSetting(); + } + case "初中" -> { + return new MiddleQuestionSetting(); + } + case "高中" -> { + return new HighQuestionSetting(); + } + default -> { + System.out.println("类型错误"); + return null; + } + } + } +} -- 2.34.1 From e1d7994bbc44067ca87e195cd95541789f3930fa Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:01:43 +0800 Subject: [PATCH 089/106] ADD file via upload --- src/User.java | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/User.java diff --git a/src/User.java b/src/User.java new file mode 100644 index 0000000..e98be23 --- /dev/null +++ b/src/User.java @@ -0,0 +1,41 @@ +public class User { + + private String username; // 用户名 + private String password; // 密码 + private String userType; //(小学/初中/高中) + + public User(String username, String password, String userType) { + this.username = username; + this.password = password; + this.userType = userType; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public boolean validateCredentials(String inputUsername, String inputPassword) { + // 验证用户名和密码是否匹配 + return this.username.equals(inputUsername) && this.password.equals(inputPassword); + } +} -- 2.34.1 From bdfc4a09486af150385874c56addf0b9f3a0feda Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 01:01:50 +0800 Subject: [PATCH 090/106] ADD file via upload --- src/UserManager.java | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/UserManager.java diff --git a/src/UserManager.java b/src/UserManager.java new file mode 100644 index 0000000..5658400 --- /dev/null +++ b/src/UserManager.java @@ -0,0 +1,63 @@ +// UserManager.java +import java.util.HashMap; +import java.util.Map; + +public class UserManager { + private Map users = new HashMap<>(); + private User currentUser; + private String currentType; + + public UserManager() { + initializeUsers(); + } + + public boolean login(String username, String password) { + if (users.containsKey(username)) { + User user = users.get(username); + if (user.validateCredentials(username, password)) { + currentUser = user; + currentType = user.getUserType(); + System.out.println("登录成功"); + return true; + } else { + System.out.println("密码错误,请重试"); + } + } else { + System.out.println("该账号不存在,请重试"); + } + return false; + } + + public void logout() { + currentUser = null; + currentType = null; + } + + public boolean switchUserType(String newType) { + if (currentUser != null) { + currentType = newType; + return true; + } + return false; + } + + public boolean isLoggedIn() { + return currentUser != null; + } + + public User getCurrentUser() { + return currentUser; + } + + private void initializeUsers() { + users.put("张三1", new User("张三1", "123", "小学")); + users.put("张三2", new User("张三2", "123", "小学")); + users.put("张三3", new User("张三3", "123", "小学")); + users.put("李四1", new User("李四1", "123", "初中")); + users.put("李四2", new User("李四2", "123", "初中")); + users.put("李四3", new User("李四3", "123", "初中")); + users.put("王五1", new User("王五1", "123", "高中")); + users.put("王五2", new User("王五2", "123", "高中")); + users.put("王五3", new User("王五3", "123", "高中")); + } +} \ No newline at end of file -- 2.34.1 From 2feb221e7a29b8c8269337e83de71686ee3dc3dc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 08:35:15 +0800 Subject: [PATCH 091/106] Update AllSystem.java --- src/AllSystem.java | 325 +++++++++++++++++++++++---------------------- 1 file changed, 164 insertions(+), 161 deletions(-) diff --git a/src/AllSystem.java b/src/AllSystem.java index d4b2278..00ff180 100644 --- a/src/AllSystem.java +++ b/src/AllSystem.java @@ -1,162 +1,165 @@ -// AllSystem.java -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -public class AllSystem { - private static final String EXIT_COMMAND = "exit"; - private static final String SWITCH_PREFIX = "切换为"; - - private Scanner scanner; - private UserManager userManager; - private FileManager fileManager; - private QuestionSettingFactory questionSettingFactory; - private QuestionSetting questionSetting; - private String tipMessage = ""; - private String currentMode = ""; - private boolean isFirstLogin = true; - - public static void clearScreen() { - try { - new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); - } catch (IOException | InterruptedException exception) { - exception.printStackTrace(); - } - } - - public void initialize() { - this.scanner = new Scanner(System.in); - userManager = new UserManager(); - fileManager = new FileManager(); - questionSettingFactory = new QuestionSettingFactory(); - questionSetting = null; - } - - public void showHomeMenu() throws IOException { - initialize(); - clearScreen(); - System.out.println("**************欢迎来到试卷生成系统**************"); - System.out.println("————————————————————————————————————————————————"); - System.out.println("请输入账号和密码(中间用空格分开,输入exit退出):"); - boolean loginSuccessful = false; - while (!loginSuccessful) { - String input = scanner.nextLine(); - if (input.isEmpty()) { - System.out.println("您的输入不符合要求,请重试"); - continue; - } - if (input.equals(EXIT_COMMAND)) { - System.exit(0); - } - String[] inputs = input.split(" "); - if (inputs.length != 2) { - System.out.println("您的输入不符合要求,请重试"); - continue; - } - if (userManager.login(inputs[0], inputs[1])) { - loginSuccessful = true; - } - } - currentMode = userManager.getCurrentUser().getUserType(); - this.questionSetting = questionSettingFactory.getQuestionSetting( - userManager.getCurrentUser().getUserType()); - setPaper(); - } - - public void setPaper() throws IOException { - clearScreen(); - if (isFirstLogin) { - System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); - isFirstLogin = false; - } else { - System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量"); - } - String input = scanner.nextLine(); - handleFirstInput(input); - } - - public void handleFirstInput(String input) throws IOException { - boolean continueProcessing = true; - while (continueProcessing) { - try { - int questionCount = Integer.parseInt(input); - if (questionCount == -1) { - continueProcessing = false; - showHomeMenu(); - } else if (10 <= questionCount && questionCount <= 30) { - List questions = new ArrayList<>(); - int remainingQuestions = questionCount; - while (remainingQuestions > 0) { - String question = questionSetting.setQuestion(3).getExpression(); - if (fileManager.checkQuestion(question, userManager.getCurrentUser())) { - questions.add(question); - System.out.println(questionCount - remainingQuestions + 1 + ". " + question); - System.out.println(); - remainingQuestions--; - } - } - fileManager.savePaper(userManager.getCurrentUser(), questions); - tipMessage = "试卷生成成功,"; - continueProcessing = false; - System.out.println("试卷生成完成!按回车键返回主菜单..."); - scanner.nextLine(); - showChoiceMenu(); - } else { - System.out.println("您的输入不符合要求,请重试"); - input = scanner.nextLine(); - } - } catch (NumberFormatException exception) { - System.out.println("您的输入不符合要求,请重试"); - input = scanner.nextLine(); - } - } - } - - public void showChoiceMenu() throws IOException { - boolean running = true; - while (running) { - clearScreen(); - System.out.println("****************欢迎光临," + userManager.getCurrentUser().getUsername() - + "****************"); - System.out.println("————————————————————————————————————————————————"); - System.out.println("当前模式是: " + currentMode); - System.out.println("0. 退出(输入0)"); - System.out.println("1. 生成试卷(输入1)"); - System.out.println("2. 切换类型(输入:切换为XX)(XX为\"初中\",\"小学\",\"高中\")"); - System.out.println(tipMessage + "请选择接下来操作:"); - - String input = scanner.nextLine(); - running = handleSecondInput(input); - } - } - - public boolean handleSecondInput(String input) throws IOException { - if (input.equals("0")) { - clearScreen(); - showHomeMenu(); - return false; - } else if (input.equals("1")) { - clearScreen(); - setPaper(); - return true; - } else if (input.length() >= 4 && input.startsWith(SWITCH_PREFIX)) { - String type = input.substring(3); - tipMessage = "切换成功,"; - if (type.equals("小学") || type.equals("初中") || type.equals("高中")) { - questionSetting = questionSettingFactory.getQuestionSetting(type); - currentMode = type; - setPaper(); - return true; - } else { - System.out.println("请输入小学、初中和高中三个选项中的一个,请按回车重试"); - scanner.nextLine(); - return true; - } - } else { - System.out.println("输入不符合要求,请按回车重试"); - scanner.nextLine(); - return true; - } - } +// AllSystem.java +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class AllSystem { + private static final String EXIT_COMMAND = "exit"; + private static final String SWITCH_PREFIX = "切换为"; + + private Scanner scanner; + private UserManager userManager; + private FileManager fileManager; + private QuestionSettingFactory questionSettingFactory; + private QuestionSetting questionSetting; + private String tipMessage; + private String currentMode; + private boolean isFirstLogin; + + public static void clearScreen() { + try { + new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); + } catch (IOException | InterruptedException exception) { + exception.printStackTrace(); + } + } + + public void initialize() { + tipMessage = ""; + currentMode = ""; + isFirstLogin = true; + this.scanner = new Scanner(System.in); + userManager = new UserManager(); + fileManager = new FileManager(); + questionSettingFactory = new QuestionSettingFactory(); + questionSetting = null; + } + + public void showHomeMenu() throws IOException { + initialize(); + clearScreen(); + System.out.println("**************欢迎来到试卷生成系统**************"); + System.out.println("————————————————————————————————————————————————"); + System.out.println("请输入账号和密码(中间用空格分开,输入exit退出):"); + boolean loginSuccessful = false; + while (!loginSuccessful) { + String input = scanner.nextLine(); + if (input.isEmpty()) { + System.out.println("您的输入不符合要求,请重试"); + continue; + } + if (input.equals(EXIT_COMMAND)) { + System.exit(0); + } + String[] inputs = input.split(" "); + if (inputs.length != 2) { + System.out.println("您的输入不符合要求,请重试"); + continue; + } + if (userManager.login(inputs[0], inputs[1])) { + loginSuccessful = true; + } + } + currentMode = userManager.getCurrentUser().getUserType(); + this.questionSetting = questionSettingFactory.getQuestionSetting( + userManager.getCurrentUser().getUserType()); + setPaper(); + } + + public void setPaper() throws IOException { + clearScreen(); + if (isFirstLogin) { + System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); + isFirstLogin = false; + } else { + System.out.println("准备生成 " + currentMode + " 数学题目,请输入生成题目数量"); + } + String input = scanner.nextLine(); + handleFirstInput(input); + } + + public void handleFirstInput(String input) throws IOException { + boolean continueProcessing = true; + while (continueProcessing) { + try { + int questionCount = Integer.parseInt(input); + if (questionCount == -1) { + continueProcessing = false; + showHomeMenu(); + } else if (10 <= questionCount && questionCount <= 30) { + List questions = new ArrayList<>(); + int remainingQuestions = questionCount; + while (remainingQuestions > 0) { + String question = questionSetting.setQuestion(3).getExpression(); + if (fileManager.checkQuestion(question, userManager.getCurrentUser())) { + questions.add(question); + System.out.println(questionCount - remainingQuestions + 1 + ". " + question); + System.out.println(); + remainingQuestions--; + } + } + fileManager.savePaper(userManager.getCurrentUser(), questions); + tipMessage = "试卷生成成功,"; + continueProcessing = false; + System.out.println("试卷生成完成!按回车键返回主菜单..."); + scanner.nextLine(); + showChoiceMenu(); + } else { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + } catch (NumberFormatException exception) { + System.out.println("您的输入不符合要求,请重试"); + input = scanner.nextLine(); + } + } + } + + public void showChoiceMenu() throws IOException { + boolean running = true; + while (running) { + clearScreen(); + System.out.println("****************欢迎光临," + userManager.getCurrentUser().getUsername() + + "****************"); + System.out.println("————————————————————————————————————————————————"); + System.out.println("当前模式是: " + currentMode); + System.out.println("-1. 退出(输入-1)"); + System.out.println("1. 生成试卷(输入1)"); + System.out.println("2. 切换类型(输入:切换为XX)(XX为\"初中\",\"小学\",\"高中\")"); + System.out.println(tipMessage + "请选择接下来操作:"); + + String input = scanner.nextLine(); + running = handleSecondInput(input); + } + } + + public boolean handleSecondInput(String input) throws IOException { + if (input.equals("-1")) { + clearScreen(); + showHomeMenu(); + return false; + } else if (input.equals("1")) { + clearScreen(); + setPaper(); + return true; + } else if (input.length() >= 4 && input.startsWith(SWITCH_PREFIX)) { + String type = input.substring(3); + tipMessage = "切换成功,"; + if (type.equals("小学") || type.equals("初中") || type.equals("高中")) { + questionSetting = questionSettingFactory.getQuestionSetting(type); + currentMode = type; + setPaper(); + return true; + } else { + System.out.println("请输入小学、初中和高中三个选项中的一个,请按回车重试"); + scanner.nextLine(); + return true; + } + } else { + System.out.println("输入不符合要求,请按回车重试"); + scanner.nextLine(); + return true; + } + } } \ No newline at end of file -- 2.34.1 From c6dd5c035ee61dc6b3fe95b6c23508f488e81877 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 08:37:45 +0800 Subject: [PATCH 092/106] Update HighQuestionSetting.java --- src/HighQuestionSetting.java | 247 +++++++++++++++++------------------ 1 file changed, 122 insertions(+), 125 deletions(-) diff --git a/src/HighQuestionSetting.java b/src/HighQuestionSetting.java index bd37cb8..9e63c4f 100644 --- a/src/HighQuestionSetting.java +++ b/src/HighQuestionSetting.java @@ -1,126 +1,123 @@ -// HighQuestionSetting.java -public class HighQuestionSetting extends AbstractQuestionSetting { - - @Override - public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { - if (child.getMainOperator() == null - || child.getMainOperator().equals("²") || child.getMainOperator().equals("√") - || child.getMainOperator().equals("sin") || child.getMainOperator().equals("cos") - || child.getMainOperator().equals("tan")) { - return child.getExpression(); - } - - int parentPriority = getPriority(parentOperator); - int childPriority = getPriority(child.getMainOperator()); - - if (childPriority < parentPriority) { - return "(" + child.getExpression() + ")"; - } - - if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { - if (parentPriority == childPriority) { - return "(" + child.getExpression() + ")"; - } - } - - return child.getExpression(); - } - - public Expression applyUnaryOperator(Expression child, String operator) { - switch (operator) { - case "²": - if (child.getMainOperator() == null) { - return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); - } - return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); - case "√": - if (child.getValue() < 0) { - String numberString = getRandomNumber(); - child = new Expression(numberString, Integer.parseInt(numberString), null); - } - if (child.getMainOperator() == null) { - return new Expression("√" + child.getExpression(), (int) Math.sqrt(child.getValue()), "√"); - } - return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); - case "sin": - return new Expression("sin(" + child.getExpression() + ")", - (int) Math.round(Math.sin(Math.toRadians(child.getValue()))), "sin"); - case "cos": - return new Expression("cos(" + child.getExpression() + ")", - (int) Math.round(Math.cos(Math.toRadians(child.getValue()))), "cos"); - case "tan": - while (child.getValue() % 180 == 90) { - String numberString = getRandomNumber(); - child = new Expression(numberString, Integer.parseInt(numberString), null); - } - return new Expression("tan(" + child.getExpression() + ")", - (int) Math.round(Math.tan(Math.toRadians(child.getValue()))), "tan"); - default: - return child; - } - } - - @Override - public Expression setQuestion(int count) { - Expression result = generateFirstQuestion(count); - while (!result.getExpression().contains("sin") && !result.getExpression().contains("cos") - && !result.getExpression().contains("tan")) { - result = generateFirstQuestion(count); - } - return result; - } - - public Expression applyProbability(Expression result) { - if (RANDOM.nextDouble() < 0.3) { - String[] unaryOperators = {"²", "√", "sin", "cos", "tan"}; - String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; - result = applyUnaryOperator(result, unaryOperator); - result.setMainOperator(unaryOperator); - } - return result; - } - - public Expression generateFirstQuestion(int count) { - if (count == 1) { - String numberString = getRandomNumber(); - int number = Integer.parseInt(numberString); - Expression expression = new Expression(numberString, number, null); - expression = applyProbability(expression); - return expression; - } - - int leftCount = 1 + RANDOM.nextInt(count - 1); - int rightCount = count - leftCount; - - Expression left = generateFirstQuestion(leftCount); - Expression right = generateFirstQuestion(rightCount); - - String operator = getRandomOperator(); - int value = 0; - switch (operator) { - case "+": - value = left.getValue() + right.getValue(); - break; - case "-": - value = left.getValue() - right.getValue(); - break; - case "*": - value = left.getValue() * right.getValue(); - break; - case "/": - if (right.getValue() == 0) { - return generateFirstQuestion(count); - } - value = left.getValue() / right.getValue(); - break; - } - - String leftExpression = addParenthesesIfNeeded(left, operator, false); - String rightExpression = addParenthesesIfNeeded(right, operator, true); - - Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, (int) value, operator); - - result = applyProbability(result); - return result; - } +// HighQuestionSetting.java +public class HighQuestionSetting extends AbstractQuestionSetting { + + @Override + public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { + if (child.getMainOperator() == null + || child.getMainOperator().equals("²") || child.getMainOperator().equals("√") + || child.getMainOperator().equals("sin") || child.getMainOperator().equals("cos") + || child.getMainOperator().equals("tan")) { + return child.getExpression(); + } + + int parentPriority = getPriority(parentOperator); + int childPriority = getPriority(child.getMainOperator()); + + if (childPriority < parentPriority) { + return "(" + child.getExpression() + ")"; + } + + if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.getExpression() + ")"; + } + } + + return child.getExpression(); + } + + public Expression applyUnaryOperator(Expression child, String operator) { + switch (operator) { + case "²": + if (child.getMainOperator() == null) { + return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); + } + return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); + case "√": + if (child.getValue() < 0) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + if (child.getMainOperator() == null) { + return new Expression("√" + child.getExpression(), (int) Math.sqrt(child.getValue()), "√"); + } + return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); + case "sin": + return new Expression("sin(" + child.getExpression() + ")", + (int) Math.round(Math.sin(Math.toRadians(child.getValue()))), "sin"); + case "cos": + return new Expression("cos(" + child.getExpression() + ")", + (int) Math.round(Math.cos(Math.toRadians(child.getValue()))), "cos"); + case "tan": + while (child.getValue() % 180 == 90) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + return new Expression("tan(" + child.getExpression() + ")", + (int) Math.round(Math.tan(Math.toRadians(child.getValue()))), "tan"); + default: + return child; + } + } + + @Override + public Expression setQuestion(int count) { + Expression result = generateFirstQuestion(count); + while (!result.getExpression().contains("sin") && !result.getExpression().contains("cos") + && !result.getExpression().contains("tan")) { + result = generateFirstQuestion(count); + } + return result; + } + + public Expression applyProbability(Expression result) { + if (RANDOM.nextDouble() < 0.3) { + String[] unaryOperators = {"²", "√", "sin", "cos", "tan"}; + String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; + result = applyUnaryOperator(result, unaryOperator); + result.setMainOperator(unaryOperator); + } + return result; + } + + public Expression generateFirstQuestion(int count) { + if (count == 1) { + String numberString = getRandomNumber(); + int number = Integer.parseInt(numberString); + Expression expression = new Expression(numberString, number, null); + expression = applyProbability(expression); + return expression; + } + int leftCount = 1 + RANDOM.nextInt(count - 1); + int rightCount = count - leftCount; + Expression left = generateFirstQuestion(leftCount); + Expression right = generateFirstQuestion(rightCount); + String operator = getRandomOperator(); + int value = 0; + switch (operator) { + case "+": + value = left.getValue() + right.getValue(); + break; + case "-": + value = left.getValue() - right.getValue(); + break; + case "*": + value = left.getValue() * right.getValue(); + break; + case "/": + if (right.getValue() == 0) { + return generateFirstQuestion(count); + } + value = left.getValue() / right.getValue(); + break; + } + + String leftExpression = addParenthesesIfNeeded(left, operator, false); + String rightExpression = addParenthesesIfNeeded(right, operator, true); + + Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, (int) value, operator); + + result = applyProbability(result); + return result; + } } \ No newline at end of file -- 2.34.1 From 883540b8581af4b9447a035cd5c8fae7bef01df0 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 08:40:02 +0800 Subject: [PATCH 093/106] Update MiddleQuestionSetting.java --- src/MiddleQuestionSetting.java | 213 ++++++++++++++++----------------- 1 file changed, 105 insertions(+), 108 deletions(-) diff --git a/src/MiddleQuestionSetting.java b/src/MiddleQuestionSetting.java index 5bde507..bf58228 100644 --- a/src/MiddleQuestionSetting.java +++ b/src/MiddleQuestionSetting.java @@ -1,109 +1,106 @@ -// MiddleQuestionSetting.java -public class MiddleQuestionSetting extends AbstractQuestionSetting { - - public Expression applyUnaryOperator(Expression child, String operator) { - switch (operator) { - case "²": - if (child.getMainOperator() == null) { - return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); - } - return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); - case "√": - if (child.getValue() < 0) { - String numberString = getRandomNumber(); - child = new Expression(numberString, Integer.parseInt(numberString), null); - } - if (child.getMainOperator() == null) { - return new Expression("√" + child.getExpression(), child.getValue() * child.getValue(), "√"); - } - return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); - default: - return child; - } - } - - @Override - public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { - if (child.getMainOperator() == null || child.getMainOperator().equals("²") || child.getMainOperator().equals("√")) { - return child.getExpression(); - } - - int parentPriority = getPriority(parentOperator); - int childPriority = getPriority(child.getMainOperator()); - - if (childPriority < parentPriority) { - return "(" + child.getExpression() + ")"; - } - - if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { - if (parentPriority == childPriority) { - return "(" + child.getExpression() + ")"; - } - } - - return child.getExpression(); - } - - @Override - public Expression setQuestion(int count) { - Expression result = generateFirstQuestion(count); - while (!result.getExpression().contains("²") && !result.getExpression().contains("√")) { - result = generateFirstQuestion(count); - } - return result; - } - - public Expression generateFirstQuestion(int count) { - if (count == 1) { - String numberString = getRandomNumber(); - int number = Integer.parseInt(numberString); - Expression expression = new Expression(numberString, number, null); - expression = applyProbability(expression); - return expression; - } - - int leftCount = 1 + RANDOM.nextInt(count - 1); - int rightCount = count - leftCount; - - Expression left = generateFirstQuestion(leftCount); - Expression right = generateFirstQuestion(rightCount); - - String operator = getRandomOperator(); - int value = 0; - switch (operator) { - case "+": - value = left.getValue() + right.getValue(); - break; - case "-": - value = left.getValue() - right.getValue(); - break; - case "*": - value = left.getValue() * right.getValue(); - break; - case "/": - while (right.getValue() == 0) { - right = generateFirstQuestion(count); - } - value = left.getValue() / right.getValue(); - break; - } - - String leftExpression = addParenthesesIfNeeded(left, operator, false); - String rightExpression = addParenthesesIfNeeded(right, operator, true); - - Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, value, operator); - - result = applyProbability(result); - return result; - } - - public Expression applyProbability(Expression result) { - if (RANDOM.nextDouble() < 0.3) { - String[] unaryOperators = {"²", "√"}; - String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; - result = applyUnaryOperator(result, unaryOperator); - result.setMainOperator(unaryOperator); - } - return result; - } +// MiddleQuestionSetting.java +public class MiddleQuestionSetting extends AbstractQuestionSetting { + + public Expression applyUnaryOperator(Expression child, String operator) { + switch (operator) { + case "²": + if (child.getMainOperator() == null) { + return new Expression(child.getExpression() + "²", child.getValue() * child.getValue(), "²"); + } + return new Expression("(" + child.getExpression() + ")²", child.getValue() * child.getValue(), "²"); + case "√": + if (child.getValue() < 0) { + String numberString = getRandomNumber(); + child = new Expression(numberString, Integer.parseInt(numberString), null); + } + if (child.getMainOperator() == null) { + return new Expression("√" + child.getExpression(), child.getValue() * child.getValue(), "√"); + } + return new Expression("√(" + child.getExpression() + ")", (int) Math.sqrt(child.getValue()), "√"); + default: + return child; + } + } + + @Override + public String addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild) { + if (child.getMainOperator() == null || child.getMainOperator().equals("²") || child.getMainOperator().equals("√")) { + return child.getExpression(); + } + + int parentPriority = getPriority(parentOperator); + int childPriority = getPriority(child.getMainOperator()); + + if (childPriority < parentPriority) { + return "(" + child.getExpression() + ")"; + } + + if (isRightChild && (parentOperator.equals("-") || parentOperator.equals("/"))) { + if (parentPriority == childPriority) { + return "(" + child.getExpression() + ")"; + } + } + + return child.getExpression(); + } + + @Override + public Expression setQuestion(int count) { + Expression result = generateFirstQuestion(count); + while (!result.getExpression().contains("²") && !result.getExpression().contains("√")) { + result = generateFirstQuestion(count); + } + return result; + } + + public Expression generateFirstQuestion(int count) { + if (count == 1) { + String numberString = getRandomNumber(); + int number = Integer.parseInt(numberString); + Expression expression = new Expression(numberString, number, null); + expression = applyProbability(expression); + return expression; + } + int leftCount = 1 + RANDOM.nextInt(count - 1); + int rightCount = count - leftCount; + Expression left = generateFirstQuestion(leftCount); + Expression right = generateFirstQuestion(rightCount); + String operator = getRandomOperator(); + int value = 0; + switch (operator) { + case "+": + value = left.getValue() + right.getValue(); + break; + case "-": + value = left.getValue() - right.getValue(); + break; + case "*": + value = left.getValue() * right.getValue(); + break; + case "/": + while (right.getValue() == 0) { + right = generateFirstQuestion(count); + } + value = left.getValue() / right.getValue(); + break; + } + + String leftExpression = addParenthesesIfNeeded(left, operator, false); + String rightExpression = addParenthesesIfNeeded(right, operator, true); + + Expression result = new Expression(leftExpression + " " + operator + " " + rightExpression, value, operator); + + result = applyProbability(result); + return result; + } + + public Expression applyProbability(Expression result) { + if (RANDOM.nextDouble() < 0.3) { + String[] unaryOperators = {"²", "√"}; + String unaryOperator = unaryOperators[RANDOM.nextInt(unaryOperators.length)]; + result = applyUnaryOperator(result, unaryOperator); + result.setMainOperator(unaryOperator); + } + return result; + } } \ No newline at end of file -- 2.34.1 From 8394e64a18a3a52b9917abfc860fcfd35bf73c15 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 16:33:34 +0800 Subject: [PATCH 094/106] =?UTF-8?q?Add=20=E8=AF=B4=E6=98=8E=E6=96=87?= =?UTF-8?q?=E6=A1=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/说明文档.md | 218 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 doc/说明文档.md diff --git a/doc/说明文档.md b/doc/说明文档.md new file mode 100644 index 0000000..cb49756 --- /dev/null +++ b/doc/说明文档.md @@ -0,0 +1,218 @@ +# 试卷生成系统说明文档 + +## 目录 +- [1. 项目概述](#1-项目概述) +- [2. 功能特性](#2-功能特性) + - [2.1 多学段支持](#21-多学段支持) + - [2.2 智能题目生成](#22-智能题目生成) + - [2.3 题目去重机制](#23-题目去重机制) + - [2.4 用户认证与管理](#24-用户认证与管理) + - [2.5 试卷保存](#25-试卷保存) + - [2.6 交互式菜单](#26-交互式菜单) +- [3. 系统架构](#3-系统架构) + - [3.1 核心模块](#31-核心模块) + - [3.2 数据流](#32-数据流) + - [3.3 扩展性](#33-扩展性) +- [4. 使用说明](#4-使用说明) + - [4.1 启动系统](#41-启动系统) + - [4.2 登录](#42-登录) + - [4.3 生成试卷](#43-生成试卷) + - [4.4 主菜单操作](#44-主菜单操作) + - [4.5 退出](#45-退出) +- [5. 文件存储结构](#5-文件存储结构) + - [5.1 目录结构](#51-目录结构) + - [5.2 文件内容格式](#52-文件内容格式) + - [5.3 去重机制](#53-去重机制) +- [6. 技术栈](#6-技术栈) +- [7. 注意事项](#7-注意事项) + - [7.1 数学精度问题](#71-数学精度问题) + - [7.2 题目去重局限性](#72-题目去重局限性) + - [7.3 系统环境要求](#73-系统环境要求) + - [7.4 安全性](#74-安全性) + - [7.5 扩展建议](#75-扩展建议) + +--- + +## 1. 项目概述 +本项目是一个面向小学、初中和高中三个学段的数学试卷自动生成系统,采用 Java 语言开发,运行于命令行环境。系统根据用户所属学段,智能生成符合该学段知识体系的数学题目,支持题目去重、试卷保存、用户登录及学段切换等功能。 + +系统内置三类题目生成策略: + +- **小学**:仅包含加、减、乘、除四则运算,确保减法结果非负、除法无零除。 +- **初中**:在小学基础上引入平方(²)与平方根(√)运算,题目中至少包含一项。 +- **高中**:进一步引入三角函数(sin、cos、tan),题目中至少包含一个三角函数表达式。 + +所有题目均以表达式形式呈现,系统自动处理运算优先级与括号逻辑,确保表达式语义清晰、格式规范。生成的试卷按用户独立存储,避免题目重复,便于教师或学生长期使用。 + +--- + +## 2. 功能特性 + +### 2.1 多学段支持 +- 支持小学、初中、高中三种用户类型。 +- 每种类型对应不同的题目生成规则与运算符集合。 +- 用户可在登录后动态切换学段(如从小学切换为高中)。 + +### 2.2 智能题目生成 +- 题目基于递归表达式树构建,结构灵活。 +- 自动处理运算优先级,合理添加括号(如 `a + b * c` 不加括号,`a * (b + c)` 加括号)。 +- 小学题目保证减法非负、除法无零除。 +- 初中/高中题目强制包含特定运算符(²/√ 或 sin/cos/tan),确保题目符合学段要求。 + +### 2.3 题目去重机制 +- 系统在生成每道题目前,会扫描该用户历史所有试卷。 +- 若发现完全相同的表达式字符串,则重新生成,确保试卷内及跨试卷无重复题目。 + +### 2.4 用户认证与管理 +- 内置 9 个预设用户(3 小学 + 3 初中 + 3 高中),用户名与密码固定。 +- 登录时验证账号密码,失败可重试。 +- 支持退出当前用户并重新登录。 + +### 2.5 试卷保存 +- 试卷以纯文本格式保存至本地文件系统。 +- 文件按用户隔离,按生成时间命名(`yyyy-MM-dd-HH-mm-ss.txt`)。 +- 每题编号并空行分隔,格式清晰易读。 + +### 2.6 交互式菜单 +提供清晰的命令行菜单,支持: +- 重新生成试卷 +- 切换学段(输入“切换为初中”等) +- 退出当前用户 +- 输入校验严格,非法输入会提示重试。 + +--- + +## 3. 系统架构 + +系统采用分层 + 工厂模式设计,结构清晰,易于扩展。 + +### 3.1 核心模块 +| 模块 | 类/接口 | 职责 | +|------------|---------|------| +| 用户管理 | User, UserManager | 管理用户信息、登录验证、当前用户状态 | +| 题目生成 | QuestionSetting(接口)
PrimaryQuestionSetting
MiddleQuestionSetting
HighQuestionSetting | 定义题目生成规范,三类实现分别对应小学、初中、高中 | +| 表达式模型 | Expression | 封装表达式字符串、计算值、主运算符 | +| 公共逻辑 | AbstractQuestionSetting | 提供随机数、运算符、优先级、括号处理等通用方法 | +| 工厂模式 | QuestionSettingFactory | 根据用户类型创建对应题目生成器 | +| 文件管理 | FileManager | 负责试卷保存与题目去重检查 | +| 主控流程 | AllSystem | 控制登录、菜单、生成、保存等全流程 | +| 程序入口 | Main | 启动系统 | + +### 3.2 数据流 +用户登录 → UserManager 验证 → 设置 currentUser +→ AllSystem 调用 QuestionSettingFactory 获取对应 QuestionSetting +→ 循环调用 `setQuestion(3)` 生成表达式 +→ 每题调用 `FileManager.checkQuestion()` 去重 +→ 题目集齐后调用 `FileManager.savePaper()` 保存 + +### 3.3 扩展性 +- 新增学段:实现 QuestionSetting 接口,注册到工厂类。 +- 新增运算符:扩展 `getPriority()` 和 `applyUnaryOperator()`。 +- 修改题目结构:调整 `generateFirstQuestion()` 递归逻辑。 + +--- + +## 4. 使用说明 + +### 4.1 启动系统 +编译并运行 `Main.java`,系统自动进入登录界面。 + +### 4.2 登录 +输入格式:`用户名 密码`(中间一个空格) + +预设账号: +- 小学:张三1、张三2、张三3(密码均为 `123`) +- 初中:李四1、李四2、李四3(密码均为 `123`) +- 高中:王五1、王五2、王五3(密码均为 `123`) + +输入 `exit` 可直接退出程序(仅在登录界面有效)。 + +### 4.3 生成试卷 +- 登录成功后,系统提示输入题目数量。 +- 输入 10 到 30 之间的整数(如 `15`)。 +- 系统逐题生成并显示,完成后提示“试卷生成完成”。 + +### 4.4 主菜单操作 +生成完成后进入主菜单,可执行以下操作: +- 输入 **1**:重新生成试卷(使用当前学段) +- 输入 **切换为小学 / 切换为初中 / 切换为高中**:切换学段并立即进入生成流程 +- 输入 **-1**:退出当前用户,返回登录界面 + +⚠️ 注意:切换学段命令必须完整输入“切换为XX”,XX只能是“小学”“初中”“高中”之一。 + +### 4.5 退出 +- 在主菜单输入 `-1` 可重新登录。 +- 在登录界面输入 `exit` 可彻底退出程序。 + +--- + +## 5. 文件存储结构 + +所有试卷保存在项目根目录下的 `./试卷/` 文件夹中,按用户隔离存储。 + +### 5.1 目录结构 + ./试卷/ + ├── 张三1/ + │ ├── 2025-09-29-14-30-22.txt + │ └── 2025-09-29-15-01-45.txt + ├── 李四1/ + │ └── 2025-09-29-14-35-10.txt + └── 王五1/ + └── 2025-09-29-14-40-33.txt +### 5.2 文件内容格式 +每份试卷为纯文本文件,内容格式如下: +45 + 23 +√(16) * 5 +sin(30) + 10 + +- 每题以 `序号. 表达式` 开头 +- 每题后空一行,便于阅读 +- 编码为 UTF-8,支持中文与数学符号 + +### 5.3 去重机制 +- 系统在保存前遍历该用户所有历史试卷文件。 +- 对每一行去除题号前缀(如 `1. `)后与新题目比对。 +- 完全相同的表达式将被跳过,重新生成新题。 + +--- + +## 6. 技术栈 + +| 类别 | 技术/工具 | +|--------|-----------| +| 编程语言 | Java 17(或兼容版本) | +| 开发范式 | 面向对象编程(OOP) | +| 设计模式 | 工厂模式、抽象类、接口 | +| 核心特性 | 递归表达式生成、运算符优先级处理、文件 I/O | +| 依赖库 | 仅使用 Java 标准库(`java.util`, `java.io`, `java.nio`, `java.time`) | +| 运行环境 | 支持 Java 的命令行终端(Windows/Linux/macOS) | +| 构建方式 | 无需构建工具,直接编译 `.java` 文件即可运行 | + +项目无第三方依赖,可直接通过 `javac` 和 `java` 命令编译运行。 + +--- + +## 7. 注意事项 + +### 7.1 数学精度问题 +- 三角函数结果被四舍五入为整数(如 `sin(30°) ≈ 0.5 → 1`),这在数学上不严谨,但便于题目简洁。实际教学中建议保留小数或使用符号形式。 +- 平方根仅对非负整数开方,负数会自动替换为新随机正数。 +- 除法为整数除法(`/` 运算符),结果向下取整(如 `7 / 3 = 2`)。 + +### 7.2 题目去重局限性 +- 去重基于字符串完全匹配,无法识别数学等价但形式不同的表达式(如 `2 + 3` 与 `3 + 2` 被视为不同题目)。 +- 若需更智能去重,需引入表达式解析与标准化模块。 + +### 7.3 系统环境要求 +- 需要 **写权限** 创建 `./试卷/` 目录及子文件。 +- 在 Windows 上使用 `cls` 清屏,Linux/macOS 用户可能看到清屏失败(可忽略或修改 `clearScreen()` 方法)。 + +### 7.4 安全性 +- 用户密码以明文硬编码在 `UserManager` 中,仅适用于演示或本地教学场景。 +- 实际部署应使用加密存储与数据库管理用户。 + +### 7.5 扩展建议 +- 增加题目难度等级(简单/中等/困难) +- 支持分数、小数、负数运算 +- 添加答案生成与校对功能 +- 开发图形用户界面(GUI)或 Web 版本 -- 2.34.1 From 214165a2785ccd085a2a76f4a729967f3e845b1a Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:05:40 +0800 Subject: [PATCH 095/106] Delete 'doc/README.md' --- doc/README.md | 56 --------------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 839034f..0000000 --- a/doc/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# 软件需求分析 - -## 1. 引言 - -该系统是为小学、初中和高中数学老师设计的,用于生成数学题目。老师通过命令行界面输入用户名和密码登录后,可以根据所选账户类型生成相应难度的数学题目,并保存为文本文件。系统应确保生成的题目不重复,并且支持账号类型切换和题目数量设置。 - -## 2. 功能需求 - -### 2.1 用户登录功能 -- **输入**:命令行输入用户名和密码,用户名和密码之间用空格隔开。 -- **验证**:系统预设小学、初中和高中三个账号(每种类型有三个账号),用户名和密码必须正确才能登录。 -- **输出**:登录成功后显示账户类型,并提示“准备生成 XX 数学题目,请输入生成题目数量”(XX 为用户登录的账户类型,如小学、初中或高中)。登录失败则提示“请输入正确的用户名、密码”,要求重新输入。 - -### 2.2 题目生成功能 -- **输入**:用户输入生成的题目数量(有效范围:10-30),输入-1则退出当前用户,重新登录。 -- **题目要求**:题目数量应在指定范围内,系统根据账号类型生成题目(小学、初中或高中难度),每道题目的操作数为1-5个,操作数取值范围为1-100。 -- **题目存储**:生成的题目将以“年-月-日-时-分-秒.txt”的形式保存到指定文件夹下,每个账号有独立的文件夹。每道题目以题号为标识,每题之间空一行。 - -### 2.3 避免重复题目 -- **要求**:同一个老师生成的卷子中的题目不能与以前已生成的题目重复。系统需要根据历史题目文件(存储在指定文件夹下)进行检查,避免题目重复生成。 - -### 2.4 账号类型切换功能 -- **输入**:在登录状态下,用户可以输入命令“切换为 XX”来切换账户类型(XX 为小学、初中和高中)。 -- **输出**:系统显示“准备生成 XX 数学题目,请输入生成题目数量”,用户输入题目数量后系统重新根据选定类型生成题目。 - -### 2.5 退出功能 -- **输入**:用户输入-1以退出当前登录状态并重新登录。 - -## 3. 系统架构设计 - -### 3.1 用户登录模块 -- **输入**:用户名和密码 -- **处理**:验证用户输入,确认是否匹配预设账号 -- **输出**:登录成功后根据账号类型显示相关信息,失败则重新提示。 - -### 3.2 题目生成模块 -- **输入**:题目数量和账户类型 -- **处理**:根据用户输入生成对应难度的数学题目,确保题目不重复,并按指定格式保存为文件。 - -### 3.3 文件管理模块 -- **输入**:生成的题目 -- **处理**:检查是否存在相同题目文件,保存新生成的题目为指定格式的文件。 -- **输出**:生成的题目文件保存在指定的文件夹中。 - -### 3.4 账号类型切换模块 -- **输入**:切换命令“切换为 XX” -- **处理**:修改当前账号类型并更新题目生成模式。 - -### 3.5 错误处理和提示模块 -- **输入**:用户的各种操作 -- **处理**:根据不同情况给出详细的错误提示和操作提示。 - -## 4. 数据库设计 - -由于题目数据和用户信息较少,系统可以采用简单的文件存储方式,而不需要使用数据库。每个用户的历史题目将保存在指定的文件夹内,文件名为“年-月-日-时-分-秒.txt”。 - -- 2.34.1 From 14cad161220caec3a03a8a7e2c7ba2098b5b8c05 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:05:57 +0800 Subject: [PATCH 096/106] =?UTF-8?q?Delete=20'doc/=E4=BF=AE=E6=94=B9AI.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/修改AI.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 doc/修改AI.md diff --git a/doc/修改AI.md b/doc/修改AI.md deleted file mode 100644 index b64d067..0000000 --- a/doc/修改AI.md +++ /dev/null @@ -1,2 +0,0 @@ -#login(): - ai只判断了用户能否登录进去,没有给出是因为该账户不存在还是因为密码不对。 \ No newline at end of file -- 2.34.1 From b4b0f3e09ddb00a8dfcd8b056b48e2d854649a71 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:14:00 +0800 Subject: [PATCH 097/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/类的设计.md | 274 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 239 insertions(+), 35 deletions(-) diff --git a/doc/类的设计.md b/doc/类的设计.md index d6dfe3a..28d3aba 100644 --- a/doc/类的设计.md +++ b/doc/类的设计.md @@ -1,35 +1,239 @@ -#类的设计 -##User(用户实体) -###作用: - 存储用户账户信息,包括用户名、密码和用户类型 -###属性: - private String username; // 用户名 - private String password; // 密码 - private String userType; // 用户类型(小学/初中/高中) -###方法: - public boolean validateCredentials(String inputUsername, String inputPassword) - // 验证用户名和密码是否匹配 - - // Getter和Setter方法 - public String getUsername() - public void setUsername(String username) - public String getPassword() - public void setPassword(String password) - public UserType getUserType() - public void setUserType(String userType) - -##UserManager(用户管理类) -###作用: - 管理用户登录状态、类型切换和用户认证 -###属性: - private Map users; // 存储所有用户信息 - private User currentUser; // 当前登录用户 - private String currentType; // 当前题目类型 -###方法: - public boolean login(String username, String password) - public void logout() - public boolean switchUserType(String newType) - public boolean isLoggedIn() - public User getCurrentUser() - private void initializeUsers() - public UserManager() +# 试卷生成系统类设计说明文档 + +本说明文档详细描述系统中各个核心类的设计目的、职责、关键属性及方法实现逻辑,帮助开发者理解系统内部结构并进行维护或扩展。 + +--- + +## 1. User 类 + +### 功能概述 +User 是用户信息的封装类,用于存储单个用户的登录凭证和所属学段类型。 + +### 属性 +- `username`:字符串类型,表示用户名。 +- `password`:字符串类型,表示用户密码(明文存储,仅用于演示)。 +- `userType`:字符串类型,表示用户类型,取值为“小学”、“初中”或“高中”。 + +### 方法 +- **构造方法** `User(String username, String password, String userType)` + 初始化用户对象,设置用户名、密码和用户类型。 + +- `getUsername()` / `setUsername(String username)` + 获取或设置用户名。 + +- `getPassword()` / `setPassword(String password)` + 获取或设置密码。 + +- `getUserType()` / `setUserType(String userType)` + 获取或设置用户类型。 + +- `validateCredentials(String inputUsername, String inputPassword)` + 验证输入的用户名和密码是否与当前用户匹配。返回布尔值,用于登录判断。 + +--- + +## 2. UserManager 类 + +### 功能概述 +UserManager 负责管理所有用户账户、处理登录逻辑,并维护当前登录用户状态。 + +### 属性 +- `users`:`Map` 类型,以用户名为键存储所有预设用户。 +- `currentUser`:`User` 类型,表示当前已登录的用户。 +- `currentType`:`String` 类型,缓存当前用户类型(冗余字段,可由 currentUser 推导)。 + +### 方法 +- **构造方法** `UserManager()` + 调用 `initializeUsers()` 初始化9个预设用户(3小学 + 3初中 + 3高中)。 + +- `initializeUsers()` + 向 users 映射中添加预设用户对象,用户名如“张三1”,密码均为“123”,类型按学段分配。 + +- `login(String username, String password)` + 实现登录逻辑: + - 若用户名不存在,提示“该账号不存在”; + - 若密码错误,提示“密码错误”; + - 验证成功,设置 `currentUser` 和 `currentType`,返回 true。 + +- `logout()` + 清空当前用户状态(设为 null)。 + +- `switchUserType(String newType)` + 允许在已登录状态下切换用户类型(实际项目中此方法未被使用,主流程通过重新获取 QuestionSetting 实现切换)。 + +- `isLoggedIn()` + 判断是否有用户登录(检查 `currentUser != null`)。 + +- `getCurrentUser()` + 返回当前登录的 `User` 对象,供其他模块获取用户信息。 + +--- + +## 3. QuestionSetting 接口 + +### 功能概述 +定义题目生成器的统一契约,确保所有学段题目生成器具有相同调用方式。 + +### 方法 +- `Expression setQuestion(int count)` + 根据指定的操作数数量 `count`(通常为3),生成一个符合当前学段要求的数学表达式对象。返回 `Expression` 实例。 + +--- + +## 4. AbstractQuestionSetting 抽象类 + +### 功能概述 +作为所有题目生成器的基类,提供通用工具方法,减少代码重复。 + +### 属性 +- `RANDOM`:静态 Random 实例,用于生成随机数,保证线程安全且全局一致。 + +### 方法 +- `getRandomOperator()` + 从 `{"+", "-", "*", "/"}` 中随机返回一个四则运算符。 + +- `getRandomNumber()` + 生成 1 到 99 的随机整数(含1和99),并返回其字符串形式。 + +- `getPriority(String operator)` + 返回运算符的优先级数值,用于括号判断: + - 三角函数、平方、开方:优先级 3 + - 乘、除:优先级 2 + - 加、减:优先级 1 + - 其他或 null:返回 0 或 -1 + +- `addParenthesesIfNeeded(Expression child, String parentOperator, boolean isRightChild)` + 根据运算优先级决定是否为子表达式添加括号: + - 子表达式无主运算符(即为纯数字),不加括号 + - 子优先级 < 父优先级,加括号 + - 若为右子表达式,且父运算符为 - 或 /,即使优先级相等也加括号(如 a - (b - c) 而非 a - b - c) + +--- + +## 5. PrimaryQuestionSetting 类(小学) + +### 功能概述 +实现小学阶段的题目生成逻辑,仅包含四则运算,并保证题目合理性。 + +### 方法 +- `setQuestion(int count)` + 递归生成表达式: + - 若 count == 1,返回一个随机数字; + - 否则将操作数拆分为左右两部分,递归生成左右子表达式; + - 随机选择运算符; + - 若为除法且右值为0,重新生成右子表达式; + - 若为减法且左值 < 右值,交换左右子表达式以保证结果非负; + - 使用 `addParenthesesIfNeeded` 处理括号; + - 返回最终表达式对象。 + +小学题目不包含任何一元运算符(如平方、三角函数),也不强制包含特定符号。 + +--- + +## 6. MiddleQuestionSetting 类(初中) + +### 功能概述 +在小学基础上增加平方(²)和平方根(√)运算,并确保每道题至少包含其中一种。 + +### 新增方法 +- `applyUnaryOperator(Expression child, String operator)` + 对子表达式应用一元运算符: + - 平方(²):若子表达式为纯数字,则直接拼接“²”;否则加括号后拼接,如 `(a + b)²` + - 平方根(√):若子值为负,替换为新随机正数;若为纯数字,前缀“√”;否则写为 `√(表达式)` + +- `applyProbability(Expression result)` + 以 30% 概率对表达式应用平方或平方根运算,并更新主运算符。 + +- `generateFirstQuestion(int count)` + 与小学类似,但每次生成后调用 `applyProbability` 尝试添加一元运算。 + +- `setQuestion(int count)` + 循环调用 `generateFirstQuestion`,直到生成的表达式包含“²”或“√”,确保题目符合初中要求。 + +--- + +## 7. HighQuestionSetting 类(高中) + +### 功能概述 +在初中基础上增加三角函数(sin、cos、tan),并确保每道题至少包含一个三角函数。 + +### 新增方法 +- `applyUnaryOperator(Expression child, String operator)` + 扩展支持三角函数: + - `sin`/`cos`:直接包裹为 `sin(表达式)` 或 `cos(表达式)`,值为 `Math.round(Math.sin(Math.toRadians(value)))` + - `tan`:若输入角度为 90 + 180k(无定义点),则替换为新随机数,避免异常 + +- `applyProbability(Expression result)` + 以 30% 概率从 `{"²", "√", "sin", "cos", "tan"}` 中随机选择一元运算符应用。 + +- `generateFirstQuestion(int count)` + 逻辑同初中,但支持更多运算符。 + +- `setQuestion(int count)` + 循环生成,直到表达式包含 `sin`、`cos` 或 `tan` 中的任意一个。 + ⚠️ 三角函数结果被强制转换为整数,可能损失精度,但简化了题目形式。 + +--- + +## 8. Expression 类 + +### 功能概述 +封装一个数学表达式的文本形式、计算值及其主运算符,用于递归构建和值传递。 + +### 属性 +- `expression`:表达式的字符串表示(如 `"5 + 3"` 或 `"√(16)"`) +- `value`:表达式计算结果的整数值 +- `mainOperator`:表达式的主运算符(如 `"+"`、`"²"`、`"sin"`),若为纯数字则为 null + +### 方法 +- 构造方法 `Expression(String expression, int value, String mainOperator)` + 初始化表达式对象 + +- `getExpression()` / `setExpression(String expression)` + 获取或设置表达式字符串 + +- `getValue()` / `setValue(int value)` + 获取或设置计算值 + +- `getMainOperator()` / `setMainOperator(String mainOperator)` + 获取或设置主运算符 + +> 该类是表达式树的节点,支持在生成过程中传递结构与值。 + +--- + +## 9. QuestionSettingFactory 类 + +### 功能概述 +工厂类,根据用户类型字符串动态创建对应的题目生成器实例。 + +### 方法 +- `getQuestionSetting(String type)` + 使用 switch 表达式: + - `"小学"` → 返回 `new PrimaryQuestionSetting()` + - `"初中"` → 返回 `new MiddleQuestionSetting()` + - `"高中"` → 返回 `new HighQuestionSetting()` + - 其他 → 打印“类型错误”,返回 `null` + +> 该类解耦了用户类型与具体实现,便于扩展新学段。 + +--- + +## 10. FileManager 类 + +### 功能概述 +负责试卷的本地存储与题目重复性检查。 + +### 常量 +- `ROOT_PATH`:根目录路径,值为 `"./试卷/"` + +### 方法 +- `savePaper(User user, List questions)` + - 创建用户专属目录(如 `./试卷/张三1/`) + - 生成时间戳文件名(格式:`yyyy-MM-dd-HH-mm-ss.txt`) + - 以 UTF-8 编码写入题目,格式为 `1. 表达式\n\n2. 表达式\n\n...` + +- `checkQuestion(String question, User user)` + - 若用户目录不存在,返回 true(无需去重) + - 遍历该用户所有历史试卷文件 + - 对每行去除题号 -- 2.34.1 From 0bf5f2860e9c299561385b1b166eb8f37f8f1cab Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:14:40 +0800 Subject: [PATCH 098/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/类的设计.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/类的设计.md b/doc/类的设计.md index 28d3aba..8e05f75 100644 --- a/doc/类的设计.md +++ b/doc/类的设计.md @@ -1,6 +1,6 @@ # 试卷生成系统类设计说明文档 -本说明文档详细描述系统中各个核心类的设计目的、职责、关键属性及方法实现逻辑,帮助开发者理解系统内部结构并进行维护或扩展。 +本说明文档详细描述系统中各个核心类的设计目的、职责、关键属性及方法实现逻辑。 --- -- 2.34.1 From f3bbed9fa3900833eb72fadd82e937e3d8f26417 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 17:25:39 +0800 Subject: [PATCH 099/106] =?UTF-8?q?Update=20=E7=B1=BB=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/类的设计.md | 69 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/doc/类的设计.md b/doc/类的设计.md index 8e05f75..d8683b5 100644 --- a/doc/类的设计.md +++ b/doc/类的设计.md @@ -11,7 +11,7 @@ User 是用户信息的封装类,用于存储单个用户的登录凭证和所 ### 属性 - `username`:字符串类型,表示用户名。 -- `password`:字符串类型,表示用户密码(明文存储,仅用于演示)。 +- `password`:字符串类型,表示用户密码。 - `userType`:字符串类型,表示用户类型,取值为“小学”、“初中”或“高中”。 ### 方法 @@ -40,7 +40,7 @@ UserManager 负责管理所有用户账户、处理登录逻辑,并维护当 ### 属性 - `users`:`Map` 类型,以用户名为键存储所有预设用户。 - `currentUser`:`User` 类型,表示当前已登录的用户。 -- `currentType`:`String` 类型,缓存当前用户类型(冗余字段,可由 currentUser 推导)。 +- `currentType`:`String` 类型,缓存当前出题类型。 ### 方法 - **构造方法** `UserManager()` @@ -76,7 +76,7 @@ UserManager 负责管理所有用户账户、处理登录逻辑,并维护当 ### 方法 - `Expression setQuestion(int count)` - 根据指定的操作数数量 `count`(通常为3),生成一个符合当前学段要求的数学表达式对象。返回 `Expression` 实例。 + 根据指定的操作数数量 `count`,生成一个符合当前学段要求的数学表达式对象。返回 `Expression` 实例。 --- @@ -233,7 +233,66 @@ UserManager 负责管理所有用户账户、处理登录逻辑,并维护当 - 生成时间戳文件名(格式:`yyyy-MM-dd-HH-mm-ss.txt`) - 以 UTF-8 编码写入题目,格式为 `1. 表达式\n\n2. 表达式\n\n...` -- `checkQuestion(String question, User user)` +- `checkQuestion(String question, User user)` - 若用户目录不存在,返回 true(无需去重) - 遍历该用户所有历史试卷文件 - - 对每行去除题号 + - 对每行去除题号,与历史文件进行匹配,如果相同则重新生成(查重功能) +> 去重基于字符串精确匹配,不进行数学等价判断。 + +--- + +## 11. AllSystem 类 + +### 功能概述 +系统的主控制器,协调用户交互、流程跳转和模块调用。 + +### 属性 +- `scanner`:`Scanner` 实例,用于读取用户输入 +- `userManager`:用户管理器 +- `fileManager`:文件管理器 +- `questionSettingFactory`:题目生成器工厂 +- `questionSetting`:当前使用的题目生成器 +- `currentMode`:当前学段类型(如“小学”) +- `isFirstLogin`:标志是否首次登录,用于提示信息 +- `tipMessage`:临时提示信息(如“切换成功”) + +### 核心方法 +- `clearScreen()` + 调用系统命令 `cls`(Windows)清屏,失败时打印堆栈(不影响主流程) + +- `initialize()` + 初始化所有组件和状态变量 + +- `showHomeMenu()` + 显示欢迎界面,循环处理登录输入,成功后进入 `setPaper()` + +- `setPaper()` + 提示用户输入题目数量(10~30),调用 `handleFirstInput` + +- `handleFirstInput(String input)` + - 输入 `-1`:返回登录界面 + - 输入 10~30:循环生成题目,调用 `checkQuestion` 去重,显示并保存 + - 其他输入:提示重试 + +- `showChoiceMenu()` + 显示主菜单,循环处理用户选择 + +- `handleSecondInput(String input)` + - 输入 `-1`:返回登录 + - 输入 `1`:重新生成试卷 + - 输入 `切换为XX`:解析类型,调用工厂切换 `questionSetting`,进入生成流程 + - 其他输入:提示重试 + +--- + +## 12. Main 类 + +### 功能概述 +程序入口类,启动整个系统。 + +### 方法 +- `main(String[] args)` + 创建 `AllSystem` 实例,调用 `showHomeMenu()` 启动交互流程 + 捕获 `IOException` 并转为运行时异常抛出 + +--- \ No newline at end of file -- 2.34.1 From 4949527e669c47266c672d970d6671ef587a13cf Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:12:52 +0800 Subject: [PATCH 100/106] Update AllSystem.java --- src/AllSystem.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/AllSystem.java b/src/AllSystem.java index 00ff180..c29cc19 100644 --- a/src/AllSystem.java +++ b/src/AllSystem.java @@ -91,7 +91,7 @@ public class AllSystem { List questions = new ArrayList<>(); int remainingQuestions = questionCount; while (remainingQuestions > 0) { - String question = questionSetting.setQuestion(3).getExpression(); + String question = questionSetting.setQuestion(getRandomNumber()).getExpression(); if (fileManager.checkQuestion(question, userManager.getCurrentUser())) { questions.add(question); System.out.println(questionCount - remainingQuestions + 1 + ". " + question); @@ -162,4 +162,13 @@ public class AllSystem { return true; } } + public int getRandomNumber() { + int count = (int) (Math.random() * 5) + 1; + if (currentMode.equals("小学")) { + if (count == 1) { + count = (int) (Math.random() * 4) + 2; + } + } + return count; + } } \ No newline at end of file -- 2.34.1 From 9b89452c452b8f19400b946b394fa36898a53acc Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:13:35 +0800 Subject: [PATCH 101/106] Update HighQuestionSetting.java --- src/HighQuestionSetting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HighQuestionSetting.java b/src/HighQuestionSetting.java index 9e63c4f..acfa2f9 100644 --- a/src/HighQuestionSetting.java +++ b/src/HighQuestionSetting.java @@ -106,7 +106,7 @@ public class HighQuestionSetting extends AbstractQuestionSetting { break; case "/": if (right.getValue() == 0) { - return generateFirstQuestion(count); + return generateFirstQuestion(rightCount); } value = left.getValue() / right.getValue(); break; -- 2.34.1 From 8ddb5cf2f79e1af1ba7e3e24cad07004838de97d Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:14:09 +0800 Subject: [PATCH 102/106] Update MiddleQuestionSetting.java --- src/MiddleQuestionSetting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MiddleQuestionSetting.java b/src/MiddleQuestionSetting.java index bf58228..95df76e 100644 --- a/src/MiddleQuestionSetting.java +++ b/src/MiddleQuestionSetting.java @@ -79,7 +79,7 @@ public class MiddleQuestionSetting extends AbstractQuestionSetting { break; case "/": while (right.getValue() == 0) { - right = generateFirstQuestion(count); + right = generateFirstQuestion(rightCount); } value = left.getValue() / right.getValue(); break; -- 2.34.1 From a597630849b99af4923f49e36a7fdfddaa62269b Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:18:23 +0800 Subject: [PATCH 103/106] =?UTF-8?q?Update=20=E8=AF=B4=E6=98=8E=E6=96=87?= =?UTF-8?q?=E6=A1=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/说明文档.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/说明文档.md b/doc/说明文档.md index cb49756..65cce5b 100644 --- a/doc/说明文档.md +++ b/doc/说明文档.md @@ -101,7 +101,7 @@ ### 3.2 数据流 用户登录 → UserManager 验证 → 设置 currentUser → AllSystem 调用 QuestionSettingFactory 获取对应 QuestionSetting -→ 循环调用 `setQuestion(3)` 生成表达式 +→ 循环调用 `setQuestion()` 生成表达式 → 每题调用 `FileManager.checkQuestion()` 去重 → 题目集齐后调用 `FileManager.savePaper()` 保存 -- 2.34.1 From cee66be3caa0d488436b17a7a22cccb91d87c295 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:33:10 +0800 Subject: [PATCH 104/106] =?UTF-8?q?Add=20=E8=BF=90=E8=A1=8C=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E6=96=87=E6=A1=A3=EF=BC=88=E8=BF=90=E8=A1=8C=E5=89=8D?= =?UTF-8?q?=E8=AF=B7=E5=85=88=E7=9C=8B=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...运行说明文档(运行前请先看) | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 doc/运行说明文档(运行前请先看) diff --git a/doc/运行说明文档(运行前请先看) b/doc/运行说明文档(运行前请先看) new file mode 100644 index 0000000..fc825aa --- /dev/null +++ b/doc/运行说明文档(运行前请先看) @@ -0,0 +1,31 @@ +# 如何执行可执行文件 + +## 1. 前提条件 +- 项目使用 **Java 17** 编译,文件编码为 **UTF-8** +- 运行前请确保电脑已安装 **Java 17 或更高版本** + +## 2. 可执行文件 +本项目提供两个可执行文件: +1. **release.jar** —— Java 可执行 JAR 包 +2. **release.bat** —— Windows 批处理文件,可直接双击运行 + +--- + +## 3. 使用 release.bat +- 双击 `release.bat` 即可启动程序 (保证和release.jar在同一个目录) +- 脚本内部已设置 UTF-8 编码,自动调用 Java 运行 `release.jar` +- 不需要手动打开终端或设置编码 + +--- + +## 4. 使用终端运行 release.jar +如果希望在终端中运行,可以按以下步骤操作: + +1. 打开 **Windows PowerShell**(或 CMD) +2. 设置终端输入输出编码为 UTF-8(PowerShell 示例): + +```powershell +[Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 +``` +3.运行 JAR 文件: +java -jar release.jar \ No newline at end of file -- 2.34.1 From e9f91459c5b50413d24df123950ad9444c51842e Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:33:47 +0800 Subject: [PATCH 105/106] =?UTF-8?q?Update=20=E8=AF=B4=E6=98=8E=E6=96=87?= =?UTF-8?q?=E6=A1=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/说明文档.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/doc/说明文档.md b/doc/说明文档.md index 65cce5b..e570e98 100644 --- a/doc/说明文档.md +++ b/doc/说明文档.md @@ -207,12 +207,3 @@ sin(30) + 10 - 需要 **写权限** 创建 `./试卷/` 目录及子文件。 - 在 Windows 上使用 `cls` 清屏,Linux/macOS 用户可能看到清屏失败(可忽略或修改 `clearScreen()` 方法)。 -### 7.4 安全性 -- 用户密码以明文硬编码在 `UserManager` 中,仅适用于演示或本地教学场景。 -- 实际部署应使用加密存储与数据库管理用户。 - -### 7.5 扩展建议 -- 增加题目难度等级(简单/中等/困难) -- 支持分数、小数、负数运算 -- 添加答案生成与校对功能 -- 开发图形用户界面(GUI)或 Web 版本 -- 2.34.1 From 3efd4ac80e57b30d4eced7d41b7a6ebaefb5ab27 Mon Sep 17 00:00:00 2001 From: hnu202304060319 <3040369688@qq.com> Date: Mon, 29 Sep 2025 18:38:05 +0800 Subject: [PATCH 106/106] =?UTF-8?q?Delete=20'doc/=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3=EF=BC=88=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E5=89=8D=E8=AF=B7=E5=85=88=E7=9C=8B=EF=BC=89'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...运行说明文档(运行前请先看) | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 doc/运行说明文档(运行前请先看) diff --git a/doc/运行说明文档(运行前请先看) b/doc/运行说明文档(运行前请先看) deleted file mode 100644 index fc825aa..0000000 --- a/doc/运行说明文档(运行前请先看) +++ /dev/null @@ -1,31 +0,0 @@ -# 如何执行可执行文件 - -## 1. 前提条件 -- 项目使用 **Java 17** 编译,文件编码为 **UTF-8** -- 运行前请确保电脑已安装 **Java 17 或更高版本** - -## 2. 可执行文件 -本项目提供两个可执行文件: -1. **release.jar** —— Java 可执行 JAR 包 -2. **release.bat** —— Windows 批处理文件,可直接双击运行 - ---- - -## 3. 使用 release.bat -- 双击 `release.bat` 即可启动程序 (保证和release.jar在同一个目录) -- 脚本内部已设置 UTF-8 编码,自动调用 Java 运行 `release.jar` -- 不需要手动打开终端或设置编码 - ---- - -## 4. 使用终端运行 release.jar -如果希望在终端中运行,可以按以下步骤操作: - -1. 打开 **Windows PowerShell**(或 CMD) -2. 设置终端输入输出编码为 UTF-8(PowerShell 示例): - -```powershell -[Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 -``` -3.运行 JAR 文件: -java -jar release.jar \ No newline at end of file -- 2.34.1