FLW 7 months ago
commit 9626c903a3

@ -1,3 +1,4 @@
<<<<<<< HEAD
中小学数学卷子自动生成系统
项目简介
中小学数学卷子自动生成系统是一个基于C++开发的命令行应用程序旨在帮助小学、初中和高中数学老师快速生成符合教学大纲要求的数学题目。系统支持题目查重、难度切换、文件保存等功能严格遵循Google C++代码规范。
@ -208,3 +209,215 @@ Fork本项目
开发者软件2303班 郭永瑞
最后更新2025年9月
版本v1.0.0
=======
中小学数学卷子自动生成系统
项目简介
中小学数学卷子自动生成系统是一个基于C++开发的命令行应用程序旨在帮助小学、初中和高中数学老师快速生成符合教学大纲要求的数学题目。系统支持题目查重、难度切换、文件保存等功能严格遵循Google C++代码规范。
功能特性
用户认证系统
预设小学、初中、高中各三个教师账户
安全的用户名密码验证机制
自动识别用户类型并设置相应难度
题目生成能力
小学题目包含加减乘除基本运算操作数2-5个
初中题目:必须包含平方(?)或开根号(√)运算符,支持单操作数
高中题目:必须包含三角函数(sin/cos/tan),支持单操作数
智能查重:避免生成重复题目
交互功能
动态难度切换(小学/初中/高中)
题目数量控制10-30题
实时题目预览
用户友好的命令行界面
文件管理
按用户分文件夹存储
时间戳命名的文件格式(年-月-日-时-分-秒.txt
题目编号和格式化输出
技术架构
类设计(面向对象)
QuestionGenerator抽象基类
├── PrimaryGenerator小学题目生成器
├── JuniorGenerator初中题目生成器
└── SeniorGenerator高中题目生成器
核心管理类:
├── AuthManager认证管理
├── SessionManager会话管理
├── FileManager文件管理
设计模式
工厂模式:题目生成器的多态实现
单一职责原则:每个类专注特定功能
开放封闭原则:易于扩展新难度级别
安装与运行
环境要求
操作系统Windows 10/11 或 Linux (WSL)
编译器GCC 8.1.0+ 支持C++17
构建工具直接使用g++
直接编译
g++ -Wall -Wextra -g3 -std=c++17 -pthread *.cpp -o output/main.exe
运行程序
chcp 65001
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
./main.exe
使用指南
登录系统
=====================================
中小学数学卷子自动生成系统
=====================================
请输入用户名和密码(格式:用户名 密码),或输入 quit 退出系统:
张三1 123
登录成功!当前选择为小学出题
=====================================
当前用户: 张三1 (小学老师)
当前出题类型: 小学
=====================================
请选择操作:
生成题目(输入题目数量 10-30
切换难度(输入:切换为小学/初中/高中)
退出登录(输入:-1
15
测试账户
用户类型 用户名 密码 默认难度
小学 张三1, 张三2, 张三3 123 小学
初中 李四1, 李四2, 李四3 123 初中
高中 王五1, 王五2, 王五3 123 高中
? 题目示例
小学题目
3 + 5 × 2 = ?
24 ÷ 3 + 7 - 2 = ?
初中题目
√(16) + 5 = ?
4? × 3 - 2 = ?
√(25) = ? (单操作数)
高中题目
sin(30°) × 2 = ?
5 + cos(45°) - 1 = ?
tan(60°) = ? (单操作数)
? 项目结构
exam/
├── src/
│ ├── main.cpp # 程序入口
│ ├── auth_manager.h/cpp # 认证管理
│ ├── question_generator.h/cpp # 题目生成基类
│ ├── primary_generator.h/cpp # 小学题目生成
│ ├── junior_generator.h/cpp # 初中题目生成
│ ├── senior_generator.h/cpp # 高中题目生成
│ ├── file_manager.h/cpp # 文件管理
│ └── session_manager.h/cpp # 会话管理
├── exams/ # 生成的题目文件
│ ├── zhangsan1/
│ ├── lisi1/
│ └── wangwu1/
├── Makefile # 编译配置
├── doc/
│ ├──README.md # 项目说明
开发指南
代码规范
遵循Google C++代码规范
使用大驼峰命名法(类名)
成员变量以下划线结尾
包含详细的注释文档
扩展新功能
添加新难度级别继承QuestionGenerator基类
修改题目规则:调整各生成器的算法参数
增强文件格式修改FileManager的输出格式
编译选项
CXX = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -I.
LDFLAGS = -pthread
故障排除
常见问题
编译错误确保GCC支持C++17检查文件路径
文件权限:确保有创建目录和文件的权限
编码问题系统使用UTF-8编码确保终端支持中文显示
调试模式
未来规划
功能增强
图形用户界面Qt版本
题目难度分级(简单/中等/困难)
答案生成和批改功能
题目导出为PDF格式
网络协作和题目共享
技术优化
单元测试覆盖
性能优化和内存管理
跨平台兼容性增强
配置文件和个性化设置
开发流程
Fork本项目
创建功能分支git checkout -b feature/AmazingFeature
提交更改git commit -m Add some AmazingFeature
推送到分支git push origin feature/AmazingFeature
开启Pull Request
致谢
感谢所有为这个项目提供建议和帮助的贡献者!
开发者软件2303班 郭永瑞
最后更新2025年9月
版本v1.0.0
>>>>>>> ca0a2fb74f33937e11a26b129d5ca535aeeed8d4

@ -1,43 +1,43 @@
#include "auth_manager.h"
#include <string>
#include <utility>
#include <unordered_map>
AuthManager::AuthManager() {
// 初始化预设的教师账户信息,包括小学、初中、高中各三个账号
accounts_ = {
{"张三1", {"123", "primary"}},
{"张三2", {"123", "primary"}},
{"张三3", {"123", "primary"}},
{"李四1", {"123", "junior"}},
{"李四2", {"123", "junior"}},
{"李四3", {"123", "junior"}},
{"王五1", {"123", "senior"}},
{"王五2", {"123", "senior"}},
{"王五3", {"123", "senior"}}
};
}
bool AuthManager::Authenticate(const std::string& username,
const std::string& password,
std::string* user_type) {
// 验证输入不包含非法字符
if (username.find(' ') != std::string::npos ||
password.find(' ') != std::string::npos) {
return false;
}
auto it = accounts_.find(username);
if (it != accounts_.end() && it->second.first == password) {
*user_type = it->second.second;
return true;
}
return false;
}
bool AuthManager::IsValidUser(const std::string& username,
const std::string& password) {
std::string user_type;
return Authenticate(username, password, &user_type);
#include "auth_manager.h"
#include <string>
#include <utility>
#include <unordered_map>
AuthManager::AuthManager() {
// 初始化预设的教师账户信息,包括小学、初中、高中各三个账号
accounts_ = {
{"张三1", {"123", "primary"}},
{"张三2", {"123", "primary"}},
{"张三3", {"123", "primary"}},
{"李四1", {"123", "junior"}},
{"李四2", {"123", "junior"}},
{"李四3", {"123", "junior"}},
{"王五1", {"123", "senior"}},
{"王五2", {"123", "senior"}},
{"王五3", {"123", "senior"}}
};
}
bool AuthManager::Authenticate(const std::string& username,
const std::string& password,
std::string* user_type) {
// 验证输入不包含非法字符
if (username.find(' ') != std::string::npos ||
password.find(' ') != std::string::npos) {
return false;
}
auto it = accounts_.find(username);
if (it != accounts_.end() && it->second.first == password) {
*user_type = it->second.second;
return true;
}
return false;
}
bool AuthManager::IsValidUser(const std::string& username,
const std::string& password) {
std::string user_type;
return Authenticate(username, password, &user_type);
}

@ -1,23 +1,23 @@
#ifndef AUTH_MANAGER_H_
#define AUTH_MANAGER_H_
#include <string>
#include <unordered_map>
class AuthManager {
public:
AuthManager();
// 用户认证返回认证结果并通过user_type输出用户类型
bool Authenticate(const std::string& username, const std::string& password,
std::string* user_type);
// 验证用户是否存在且密码正确
bool IsValidUser(const std::string& username, const std::string& password);
private:
// 存储账户信息:用户名 -> (密码, 用户类型)
std::unordered_map<std::string, std::pair<std::string, std::string>> accounts_;
};
#ifndef AUTH_MANAGER_H_
#define AUTH_MANAGER_H_
#include <string>
#include <unordered_map>
class AuthManager {
public:
AuthManager();
// 用户认证返回认证结果并通过user_type输出用户类型
bool Authenticate(const std::string& username, const std::string& password,
std::string* user_type);
// 验证用户是否存在且密码正确
bool IsValidUser(const std::string& username, const std::string& password);
private:
// 存储账户信息:用户名 -> (密码, 用户类型)
std::unordered_map<std::string, std::pair<std::string, std::string>> accounts_;
};
#endif // AUTH_MANAGER_H_

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include "file_manager.h"
#include <iostream>
@ -199,4 +200,180 @@ std::string FileManager::CleanQuestionText(std::string question_text) {
question_text.pop_back();
}
return question_text;
=======
#include "file_manager.h"
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
#include <direct.h> // Windows目录操作
#include <windows.h> // Windows API
#include <unordered_map>
std::string FileManager::UsernameToPinyin(const std::string& username) {
// 用户名到拼音的映射
static const std::unordered_map<std::string, std::string> name_map = {
{"张三1", "zhangsan1"},
{"张三2", "zhangsan2"},
{"张三3", "zhangsan3"},
{"李四1", "lisi1"},
{"李四2", "lisi2"},
{"李四3", "lisi3"},
{"王五1", "wangwu1"},
{"王五2", "wangwu2"},
{"王五3", "wangwu3"}
};
auto it = name_map.find(username);
if (it != name_map.end()) {
return it->second;
}
// 如果没有找到映射,返回原用户名
return username;
}
bool FileManager::CreateUserDirectory(const std::string& username) {
std::string pinyin_username = UsernameToPinyin(username);
const std::string dir_path = std::string(kBasePath) + pinyin_username;
// 先创建基础目录(如果不存在)
_mkdir(kBasePath);
// 使用Windows API创建用户目录
if (CreateDirectoryA(dir_path.c_str(), NULL)) {
return true;
} else {
// 如果目录已存在ERROR_ALREADY_EXISTS是正常的
return GetLastError() == ERROR_ALREADY_EXISTS;
}
}
std::string FileManager::GenerateFilename() {
std::time_t now = std::time(nullptr);
std::tm local_time;
localtime_s(&local_time, &now); // 使用安全的版本
char buffer[80];
std::strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", &local_time);
return std::string(buffer) + ".txt";
}
bool FileManager::SaveQuestions(const std::string& username,
const std::vector<std::string>& questions) {
if (questions.empty()) {
std::cerr << "错误:问题列表为空" << std::endl;
return false;
}
// 确保用户目录存在
if (!CreateUserDirectory(username)) {
std::cerr << "错误:无法创建用户目录: " << username << std::endl;
return false;
}
std::string pinyin_username = UsernameToPinyin(username);
const std::string dir_path = std::string(kBasePath) + pinyin_username;
const std::string filename = GenerateFilename();
const std::string full_path = dir_path + "\\" + filename;
std::ofstream file(full_path);
if (!file.is_open()) {
std::cerr << "错误:无法创建文件: " << full_path << std::endl;
return false;
}
// 写入文件头信息
file << "用户名: " << username << " (" << pinyin_username << ")\n";
file << "生成时间: " << filename.substr(0, filename.length() - 4) << "\n";
file << "题目数量: " << questions.size() << "\n";
file << "==============================\n\n";
// 写入题目
for (size_t i = 0; i < questions.size(); ++i) {
file << "" << (i + 1) << "题: " << questions[i] << "\n\n";
}
file.close();
std::cout << "✓ 题目已保存至: " << full_path << std::endl;
return true;
}
bool FileManager::IsQuestionExists(const std::string& username,
const std::string& question) {
const auto existing_questions = LoadExistingQuestions(username);
// 简单的字符串匹配(可改进为模糊匹配)
for (const auto& existing : existing_questions) {
if (existing.find(question) != std::string::npos ||
question.find(existing) != std::string::npos) {
return true;
}
}
return false;
}
std::vector<std::string> FileManager::LoadExistingQuestions(const std::string& username) {
std::vector<std::string> questions;
std::string pinyin_username = UsernameToPinyin(username);
const std::string dir_path = std::string(kBasePath) + pinyin_username;
const std::string search_path = dir_path + "\\*.txt";
// 检查目录是否存在
DWORD attrib = GetFileAttributesA(dir_path.c_str());
if (attrib == INVALID_FILE_ATTRIBUTES || !(attrib & FILE_ATTRIBUTE_DIRECTORY)) {
return questions; // 目录不存在
}
WIN32_FIND_DATAA find_file_data;
HANDLE h_find = FindFirstFileA(search_path.c_str(), &find_file_data);
if (h_find == INVALID_HANDLE_VALUE) {
return questions; // 没有找到文件
}
do {
if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
const std::string filename = find_file_data.cFileName;
const std::string file_path = dir_path + "\\" + filename;
std::ifstream file(file_path);
if (file.is_open()) {
std::string line;
bool in_questions_section = false;
while (std::getline(file, line)) {
// 跳过文件头,直到分隔线
if (line.find("==============================") != std::string::npos) {
in_questions_section = true;
continue;
}
if (in_questions_section && !line.empty()) {
// 匹配 "第X题: " 格式
if (line.find("") == 0 && line.find("题: ") != std::string::npos) {
size_t pos = line.find("题: ");
if (pos != std::string::npos) {
std::string question_text = line.substr(pos + 3); // "题: " 长度是3
// 移除Windows换行符
if (!question_text.empty() && question_text.back() == '\r') {
question_text.pop_back();
}
if (!question_text.empty()) {
questions.push_back(question_text);
}
}
}
}
}
file.close();
}
}
} while (FindNextFileA(h_find, &find_file_data) != 0);
FindClose(h_find);
return questions;
>>>>>>> ca0a2fb74f33937e11a26b129d5ca535aeeed8d4
}

@ -1,3 +1,4 @@
<<<<<<< HEAD
#ifndef FILE_MANAGER_H_
#define FILE_MANAGER_H_
@ -37,4 +38,33 @@ class FileManager {
FileManager& operator=(const FileManager&) = delete;
};
=======
#ifndef FILE_MANAGER_H_
#define FILE_MANAGER_H_
#include <string>
#include <vector>
class FileManager {
public:
FileManager() = default;
bool CreateUserDirectory(const std::string& username);
std::string GenerateFilename();
bool SaveQuestions(const std::string& username,
const std::vector<std::string>& questions);
bool IsQuestionExists(const std::string& username,
const std::string& question);
std::vector<std::string> LoadExistingQuestions(const std::string& username);
private:
static constexpr const char* kBasePath = "exams\\"; // Windows·<73><C2B7><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>
// <20><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>
FileManager(const FileManager&) = delete;
FileManager& operator=(const FileManager&) = delete;
std::string UsernameToPinyin(const std::string& username);
};
>>>>>>> ca0a2fb74f33937e11a26b129d5ca535aeeed8d4
#endif // FILE_MANAGER_H_

@ -1,76 +1,76 @@
#include "junior_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> JuniorGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count);
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string JuniorGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
bool has_special_operator = false;
// 第一个操作数可以是普通数字或特殊运算符
if (operand_count == 1 || GetRandomNumber(0, 1)) {
// 单操作数情况或第一个操作数是特殊运算符
if (GetRandomNumber(0, 1)) {
ss << "sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << GetRandomNumber(1, 10) << "^2";
}
has_special_operator = true;
} else {
// 第一个操作数是普通数字
ss << GetRandomNumber(kMinNumber, kMaxNumber);
}
// 添加后续操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
// 随机决定是添加普通数字还是特殊运算符
if (!has_special_operator || GetRandomNumber(0, 1)) {
if (GetRandomNumber(0, 1)) {
ss << " " << op << " sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << " " << op << " " << GetRandomNumber(1, 10) << "^2";
}
has_special_operator = true;
} else {
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
}
// 确保至少有一个特殊运算符
if (!has_special_operator) {
const char op = GetRandomOperator(kOperators);
if (GetRandomNumber(0, 1)) {
ss << " " << op << " sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << " " << op << " " << GetRandomNumber(1, 10) << "^2";
}
}
ss << " = ?";
return ss.str();
}
bool JuniorGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 使用ASCII字符而不是特殊Unicode字符
return question.find("^2") != std::string::npos ||
question.find("sqrt") != std::string::npos;
#include "junior_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> JuniorGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count);
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string JuniorGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
bool has_special_operator = false;
// 第一个操作数可以是普通数字或特殊运算符
if (operand_count == 1 || GetRandomNumber(0, 1)) {
// 单操作数情况或第一个操作数是特殊运算符
if (GetRandomNumber(0, 1)) {
ss << "sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << GetRandomNumber(1, 10) << "^2";
}
has_special_operator = true;
} else {
// 第一个操作数是普通数字
ss << GetRandomNumber(kMinNumber, kMaxNumber);
}
// 添加后续操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
// 随机决定是添加普通数字还是特殊运算符
if (!has_special_operator || GetRandomNumber(0, 1)) {
if (GetRandomNumber(0, 1)) {
ss << " " << op << " sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << " " << op << " " << GetRandomNumber(1, 10) << "^2";
}
has_special_operator = true;
} else {
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
}
// 确保至少有一个特殊运算符
if (!has_special_operator) {
const char op = GetRandomOperator(kOperators);
if (GetRandomNumber(0, 1)) {
ss << " " << op << " sqrt(" << GetRandomNumber(kMinNumber, kMaxNumber) << ")";
} else {
ss << " " << op << " " << GetRandomNumber(1, 10) << "^2";
}
}
ss << " = ?";
return ss.str();
}
bool JuniorGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 使用ASCII字符而不是特殊Unicode字符
return question.find("^2") != std::string::npos ||
question.find("sqrt") != std::string::npos;
}

@ -1,21 +1,21 @@
#ifndef JUNIOR_GENERATOR_H_
#define JUNIOR_GENERATOR_H_
#include "question_generator.h"
class JuniorGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 1;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
std::string GenerateSingleQuestion();
};
#ifndef JUNIOR_GENERATOR_H_
#define JUNIOR_GENERATOR_H_
#include "question_generator.h"
class JuniorGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 1;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
std::string GenerateSingleQuestion();
};
#endif // JUNIOR_GENERATOR_H_

@ -1,3 +1,4 @@
<<<<<<< HEAD
#include <iostream>
#include <string>
#include <sstream>
@ -214,4 +215,161 @@ int main() {
}
return 0;
=======
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#include "auth_manager.h"
#include "session_manager.h"
#include "file_manager.h"
// 显示欢迎界面
void ShowWelcome() {
std::cout << "=====================================" << std::endl;
std::cout << " 中小学数学卷子自动生成系统" << std::endl;
std::cout << "=====================================" << std::endl;
}
// 显示主菜单
void ShowMainMenu(const std::string& username, const std::string& difficulty) {
std::cout << "\n=====================================" << std::endl;
std::cout << "当前用户: " << username << " (" << difficulty << "老师)" << std::endl;
std::cout << "当前出题类型: " << difficulty << std::endl;
std::cout << "=====================================" << std::endl;
std::cout << "请选择操作:" << std::endl;
std::cout << "1. 生成题目(输入题目数量 10-30" << std::endl;
std::cout << "2. 切换难度(输入:切换为小学/初中/高中)" << std::endl;
std::cout << "3. 退出登录(输入:-1" << std::endl;
std::cout << "> ";
}
int main() {
AuthManager auth_manager;
SessionManager session_manager;
FileManager file_manager;
while (true) {
ShowWelcome();
std::cout << "请输入用户名和密码(格式:用户名 密码),或输入 quit 退出系统:" << std::endl; // 修改提示
std::cout << "> ";
std::string input;
std::getline(std::cin, input);
// 去除前后空格
input.erase(0, input.find_first_not_of(" "));
input.erase(input.find_last_not_of(" ") + 1);
// 检查是否要退出系统(只在首页)
if (input == "quit" || input == "exit" || input == "退出") {
std::cout << "感谢使用中小学数学卷子自动生成系统,再见!" << std::endl;
break; // 退出整个程序
}
std::istringstream iss(input);
std::string username, password;
iss >> username >> password;
// 检查输入格式
if (username.empty() || password.empty()) {
std::cout << "请输入正确的用户名、密码" << std::endl;
continue;
}
// 检查是否正好有两个token
std::vector<std::string> tokens;
std::string token;
while (iss >> token) {
tokens.push_back(token);
}
if (!tokens.empty()) { // 如果还有更多token说明输入格式错误
std::cout << "输入格式错误:请输入用户名和密码,用空格分隔" << std::endl;
continue;
}
std::string user_type;
if (auth_manager.Authenticate(username, password, &user_type)) {
const char* difficulty_name =
(user_type == "primary") ? "小学" :
(user_type == "junior") ? "初中" : "高中";
std::cout << "登录成功!当前选择为" << difficulty_name << "出题" << std::endl;
session_manager.SetUser(username, user_type);
file_manager.CreateUserDirectory(username);
// 主循环
bool logged_in = true;
while (logged_in) {
ShowMainMenu(username, session_manager.GetCurrentDifficulty());
std::string command;
std::getline(std::cin, command);
// 去除前后空格
command.erase(0, command.find_first_not_of(" "));
command.erase(command.find_last_not_of(" ") + 1);
if (command.empty()) {
continue;
}
// 首先检查退出命令
if (command == "-1") {
std::cout << "退出当前用户,重新登录..." << std::endl;
logged_in = false;
continue;
}
// 检查切换难度命令
if (command.find("切换为") == 0) {
std::string new_difficulty = command.substr(9);
if (new_difficulty == "小学" || new_difficulty == "初中" || new_difficulty == "高中") {
std::string difficulty_type =
(new_difficulty == "小学") ? "primary" :
(new_difficulty == "初中") ? "junior" : "senior";
if (session_manager.SwitchDifficulty(difficulty_type)) {
std::cout << "切换成功!当前出题类型: " << new_difficulty << std::endl;
}
} else {
std::cout << "请输入小学、初中和高中三个选项中的一个" << std::endl;
}
continue;
}
// 尝试解析为数字(题目数量)
try {
int count = std::stoi(command);
if (count >= 10 && count <= 30) {
std::cout << "正在生成" << session_manager.GetCurrentDifficulty()
<< "数学题目,数量: " << count << "..." << std::endl;
QuestionGenerator* generator = session_manager.GetCurrentGenerator();
auto questions = generator->GenerateQuestions(count, username);
if (file_manager.SaveQuestions(username, questions)) {
std::cout << "题目生成完成!已保存到文件。" << std::endl;
} else {
std::cout << "文件保存失败!" << std::endl;
}
} else {
std::cout << "题目数量范围应为10-30请重新输入" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "无效命令,请重新输入" << std::endl;
std::cout << "有效命令10-30生成题目、-1退出登录、切换为小学/初中/高中" << std::endl;
}
}
} else {
std::cout << "请输入正确的用户名、密码" << std::endl;
}
}
return 0;
>>>>>>> ca0a2fb74f33937e11a26b129d5ca535aeeed8d4
}

@ -1,42 +1,42 @@
#include "primary_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> PrimaryGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count); // 预分配空间提高效率
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string PrimaryGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
ss << GetRandomNumber(kMinNumber, kMaxNumber); // 第一个操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
ss << " = ?";
return ss.str();
}
bool PrimaryGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 小学题目只需要包含基本运算符:+ - * /
return question.find('+') != std::string::npos ||
question.find('-') != std::string::npos ||
question.find('*') != std::string::npos ||
question.find('/') != std::string::npos;
#include "primary_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> PrimaryGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count); // 预分配空间提高效率
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string PrimaryGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
ss << GetRandomNumber(kMinNumber, kMaxNumber); // 第一个操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
ss << " = ?";
return ss.str();
}
bool PrimaryGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 小学题目只需要包含基本运算符:+ - * /
return question.find('+') != std::string::npos ||
question.find('-') != std::string::npos ||
question.find('*') != std::string::npos ||
question.find('/') != std::string::npos;
}

@ -1,21 +1,21 @@
#ifndef PRIMARY_GENERATOR_H_
#define PRIMARY_GENERATOR_H_
#include "question_generator.h"
class PrimaryGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 2;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
std::string GenerateSingleQuestion();
};
#ifndef PRIMARY_GENERATOR_H_
#define PRIMARY_GENERATOR_H_
#include "question_generator.h"
class PrimaryGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 2;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
std::string GenerateSingleQuestion();
};
#endif // PRIMARY_GENERATOR_H_

@ -1,19 +1,19 @@
#include "question_generator.h"
#include <chrono>
#include <random>
QuestionGenerator::QuestionGenerator() {
rng_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
}
int QuestionGenerator::GetRandomNumber(int min, int max) {
std::uniform_int_distribution<int> dist(min, max);
return dist(rng_);
}
char QuestionGenerator::GetRandomOperator(const std::vector<char>& operators) {
if (operators.empty()) return '+';
std::uniform_int_distribution<int> dist(0, operators.size() - 1);
return operators[dist(rng_)];
#include "question_generator.h"
#include <chrono>
#include <random>
QuestionGenerator::QuestionGenerator() {
rng_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
}
int QuestionGenerator::GetRandomNumber(int min, int max) {
std::uniform_int_distribution<int> dist(min, max);
return dist(rng_);
}
char QuestionGenerator::GetRandomOperator(const std::vector<char>& operators) {
if (operators.empty()) return '+';
std::uniform_int_distribution<int> dist(0, operators.size() - 1);
return operators[dist(rng_)];
}

@ -1,37 +1,37 @@
#ifndef QUESTION_GENERATOR_H_
#define QUESTION_GENERATOR_H_
#include <string>
#include <vector>
#include <random>
class QuestionGenerator {
public:
virtual ~QuestionGenerator() = default;
// 生成指定数量的数学题目
virtual std::vector<std::string> GenerateQuestions(int count,
const std::string& username) = 0;
// 检查题目是否符合难度要求
virtual bool MeetsDifficultyRequirements(const std::string& question) = 0;
protected:
QuestionGenerator();
// 生成指定范围内的随机数
int GetRandomNumber(int min, int max);
// 从运算符列表中随机选择一个运算符
char GetRandomOperator(const std::vector<char>& operators);
std::string current_user_;
std::mt19937 rng_;
private:
// 禁用拷贝构造和赋值操作
QuestionGenerator(const QuestionGenerator&) = delete;
QuestionGenerator& operator=(const QuestionGenerator&) = delete;
};
#ifndef QUESTION_GENERATOR_H_
#define QUESTION_GENERATOR_H_
#include <string>
#include <vector>
#include <random>
class QuestionGenerator {
public:
virtual ~QuestionGenerator() = default;
// 生成指定数量的数学题目
virtual std::vector<std::string> GenerateQuestions(int count,
const std::string& username) = 0;
// 检查题目是否符合难度要求
virtual bool MeetsDifficultyRequirements(const std::string& question) = 0;
protected:
QuestionGenerator();
// 生成指定范围内的随机数
int GetRandomNumber(int min, int max);
// 从运算符列表中随机选择一个运算符
char GetRandomOperator(const std::vector<char>& operators);
std::string current_user_;
std::mt19937 rng_;
private:
// 禁用拷贝构造和赋值操作
QuestionGenerator(const QuestionGenerator&) = delete;
QuestionGenerator& operator=(const QuestionGenerator&) = delete;
};
#endif // QUESTION_GENERATOR_H_

@ -1,72 +1,72 @@
#include "senior_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> SeniorGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count);
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string SeniorGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
static const std::vector<std::string> kTrigFunctions = {"sin", "cos", "tan"};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
bool has_trig_function = false;
// 第一个操作数可以是普通数字或三角函数
if (operand_count == 1 || GetRandomNumber(0, 1)) {
// 单操作数情况或第一个操作数是三角函数
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
has_trig_function = true;
} else {
// 第一个操作数是普通数字
ss << GetRandomNumber(kMinNumber, kMaxNumber);
}
// 添加后续操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
// 随机决定是添加普通数字还是三角函数
if (!has_trig_function || GetRandomNumber(0, 1)) {
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << " " << op << " " << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
has_trig_function = true;
} else {
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
}
// 确保至少有一个三角函数
if (!has_trig_function) {
const char op = GetRandomOperator(kOperators);
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << " " << op << " " << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
}
ss << " = ?";
return ss.str();
}
bool SeniorGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 高中题目至少包含一个三角函数
return question.find("sin") != std::string::npos ||
question.find("cos") != std::string::npos ||
question.find("tan") != std::string::npos;
#include "senior_generator.h"
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> SeniorGenerator::GenerateQuestions(int count,
const std::string& username) {
current_user_ = username;
std::vector<std::string> questions;
questions.reserve(count);
for (int i = 0; i < count; ++i) {
questions.push_back(GenerateSingleQuestion());
}
return questions;
}
std::string SeniorGenerator::GenerateSingleQuestion() {
static const std::vector<char> kOperators = {'+', '-', '*', '/'};
static const std::vector<std::string> kTrigFunctions = {"sin", "cos", "tan"};
const int operand_count = GetRandomNumber(kMinOperands, kMaxOperands);
std::stringstream ss;
bool has_trig_function = false;
// 第一个操作数可以是普通数字或三角函数
if (operand_count == 1 || GetRandomNumber(0, 1)) {
// 单操作数情况或第一个操作数是三角函数
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
has_trig_function = true;
} else {
// 第一个操作数是普通数字
ss << GetRandomNumber(kMinNumber, kMaxNumber);
}
// 添加后续操作数
for (int i = 1; i < operand_count; ++i) {
const char op = GetRandomOperator(kOperators);
// 随机决定是添加普通数字还是三角函数
if (!has_trig_function || GetRandomNumber(0, 1)) {
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << " " << op << " " << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
has_trig_function = true;
} else {
ss << " " << op << " " << GetRandomNumber(kMinNumber, kMaxNumber);
}
}
// 确保至少有一个三角函数
if (!has_trig_function) {
const char op = GetRandomOperator(kOperators);
const int trig_index = GetRandomNumber(0, kTrigFunctions.size() - 1);
ss << " " << op << " " << kTrigFunctions[trig_index] << "("
<< GetRandomNumber(kMinNumber, kMaxAngle) << "°)";
}
ss << " = ?";
return ss.str();
}
bool SeniorGenerator::MeetsDifficultyRequirements(const std::string& question) {
// 高中题目至少包含一个三角函数
return question.find("sin") != std::string::npos ||
question.find("cos") != std::string::npos ||
question.find("tan") != std::string::npos;
}

@ -1,22 +1,22 @@
#ifndef SENIOR_GENERATOR_H_
#define SENIOR_GENERATOR_H_
#include "question_generator.h"
class SeniorGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 1;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
static constexpr int kMaxAngle = 90;
std::string GenerateSingleQuestion();
};
#ifndef SENIOR_GENERATOR_H_
#define SENIOR_GENERATOR_H_
#include "question_generator.h"
class SeniorGenerator : public QuestionGenerator {
public:
std::vector<std::string> GenerateQuestions(int count,
const std::string& username) override;
bool MeetsDifficultyRequirements(const std::string& question) override;
private:
static constexpr int kMinOperands = 1;
static constexpr int kMaxOperands = 5;
static constexpr int kMinNumber = 1;
static constexpr int kMaxNumber = 100;
static constexpr int kMaxAngle = 90;
std::string GenerateSingleQuestion();
};
#endif // SENIOR_GENERATOR_H_

@ -1,40 +1,40 @@
#include "session_manager.h"
SessionManager::SessionManager()
: current_user_(""),
current_difficulty_(""),
current_generator_(nullptr) {}
void SessionManager::SetUser(const std::string& username,
const std::string& difficulty) {
current_user_ = username;
SwitchDifficulty(difficulty);
}
bool SessionManager::SwitchDifficulty(const std::string& difficulty) {
if (difficulty == "primary") {
current_generator_ = &primary_generator_;
current_difficulty_ = "小学";
} else if (difficulty == "junior") {
current_generator_ = &junior_generator_;
current_difficulty_ = "初中";
} else if (difficulty == "senior") {
current_generator_ = &senior_generator_;
current_difficulty_ = "高中";
} else {
return false;
}
return true;
}
QuestionGenerator* SessionManager::GetCurrentGenerator() {
return current_generator_;
}
std::string SessionManager::GetCurrentDifficulty() const {
return current_difficulty_;
}
std::string SessionManager::GetCurrentUser() const {
return current_user_;
#include "session_manager.h"
SessionManager::SessionManager()
: current_user_(""),
current_difficulty_(""),
current_generator_(nullptr) {}
void SessionManager::SetUser(const std::string& username,
const std::string& difficulty) {
current_user_ = username;
SwitchDifficulty(difficulty);
}
bool SessionManager::SwitchDifficulty(const std::string& difficulty) {
if (difficulty == "primary") {
current_generator_ = &primary_generator_;
current_difficulty_ = "小学";
} else if (difficulty == "junior") {
current_generator_ = &junior_generator_;
current_difficulty_ = "初中";
} else if (difficulty == "senior") {
current_generator_ = &senior_generator_;
current_difficulty_ = "高中";
} else {
return false;
}
return true;
}
QuestionGenerator* SessionManager::GetCurrentGenerator() {
return current_generator_;
}
std::string SessionManager::GetCurrentDifficulty() const {
return current_difficulty_;
}
std::string SessionManager::GetCurrentUser() const {
return current_user_;
}

@ -1,43 +1,43 @@
#ifndef SESSION_MANAGER_H_
#define SESSION_MANAGER_H_
#include <string>
#include "question_generator.h"
#include "primary_generator.h"
#include "junior_generator.h"
#include "senior_generator.h"
class SessionManager {
public:
SessionManager();
// 设置当前用户和难度
void SetUser(const std::string& username, const std::string& difficulty);
// 切换难度级别
bool SwitchDifficulty(const std::string& difficulty);
// 获取当前题目生成器
QuestionGenerator* GetCurrentGenerator();
// 获取当前难度描述
std::string GetCurrentDifficulty() const;
// 获取当前用户名
std::string GetCurrentUser() const;
private:
std::string current_user_;
std::string current_difficulty_;
QuestionGenerator* current_generator_;
PrimaryGenerator primary_generator_;
JuniorGenerator junior_generator_;
SeniorGenerator senior_generator_;
// 禁用拷贝构造和赋值操作
SessionManager(const SessionManager&) = delete;
SessionManager& operator=(const SessionManager&) = delete;
};
#ifndef SESSION_MANAGER_H_
#define SESSION_MANAGER_H_
#include <string>
#include "question_generator.h"
#include "primary_generator.h"
#include "junior_generator.h"
#include "senior_generator.h"
class SessionManager {
public:
SessionManager();
// 设置当前用户和难度
void SetUser(const std::string& username, const std::string& difficulty);
// 切换难度级别
bool SwitchDifficulty(const std::string& difficulty);
// 获取当前题目生成器
QuestionGenerator* GetCurrentGenerator();
// 获取当前难度描述
std::string GetCurrentDifficulty() const;
// 获取当前用户名
std::string GetCurrentUser() const;
private:
std::string current_user_;
std::string current_difficulty_;
QuestionGenerator* current_generator_;
PrimaryGenerator primary_generator_;
JuniorGenerator junior_generator_;
SeniorGenerator senior_generator_;
// 禁用拷贝构造和赋值操作
SessionManager(const SessionManager&) = delete;
SessionManager& operator=(const SessionManager&) = delete;
};
#endif // SESSION_MANAGER_H_
Loading…
Cancel
Save