diff --git a/doc/readme.md b/doc/readme.md index 1a64046..241b61d 100644 --- a/doc/readme.md +++ b/doc/readme.md @@ -9,3 +9,5 @@ [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 **3**.运行时会生成若干文件夹用于存储试题; + +4.编译版本为C++11以上 diff --git a/src/main.cpp b/src/main.cpp index ba76e19..c8cd0f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -20,21 +21,289 @@ using namespace std; -// 账户结构体 +// 账户结构体:存储用户账户信息 struct Account { - string username; - string password; - string type; // 用户类型:小学、初中、高中 + string username; // 用户名 + string password; // 密码 + string type; // 用户类型:小学、初中、高中 }; -// 数学卷子生成主类 +// 抽象题目生成器:定义题目生成器的统一接口 +class MathQuestionGenerator { +public: + virtual ~MathQuestionGenerator() {} + virtual std::string generateQuestion() = 0; // 生成题目的纯虚函数 +}; + +// 小学题目生成器:生成小学级别的数学题目 +class PrimaryQuestionGenerator : public MathQuestionGenerator { +public: + PrimaryQuestionGenerator() {} + + // 生成指定范围内的随机数 + int randomNumber(int min, int max) { + return rand() % (max - min + 1) + min; + } + + // 构建数学表达式字符串 + std::string buildExpression(const std::vector& operands, const std::vector& operators) { + size_t n = operands.size(); + // 简单情况:只有两个操作数 + if (n == 2) { + return std::to_string(operands[0]) + " " + std::string(1, operators[0]) + " " + std::to_string(operands[1]); + } + + // 随机选择括号位置 + size_t l = 1, r = n - 2; + if (r > l) { + l = 1 + rand() % (n - 2); + size_t max_r = n - 2; + size_t range = max_r - l; + if (range == 0) { + r = l + 1; + } else { + r = l + 1 + rand() % range; + } + } else { + l = 1; + r = 2; + } + + // 构建带括号的表达式 + std::string expression; + for (size_t i = 0; i < n; i++) { + if (i == l) expression += "("; + expression += std::to_string(operands[i]); + if (i < operators.size()) { + expression += " " + std::string(1, operators[i]) + " "; + } + if (i == r) expression += ")"; + } + return expression; + } + + // 生成小学题目:包含加减乘除运算,支持括号 + std::string generateQuestion() override { + int operandCount = randomNumber(2, 5); // 操作数数量:2-5个 + std::vector operands; + std::vector operators; + + // 生成第一个操作数 + operands.push_back(randomNumber(1, 100)); + + // 生成后续操作数和运算符 + for (int i = 0; i < operandCount - 1; i++) { + int opType = randomNumber(0, 3); // 随机选择运算符类型 + int prev = operands.back(); + int next; + + switch (opType) { + case 0: // 加法 + next = randomNumber(1, 100); + operators.push_back('+'); + operands.push_back(next); + break; + case 1: // 减法(确保结果非负) + next = randomNumber(1, prev); + operators.push_back('-'); + operands.push_back(next); + break; + case 2: // 乘法 + next = randomNumber(1, 100); + operators.push_back('*'); + operands.push_back(next); + break; + case 3: // 除法(确保能整除) + next = randomNumber(1, 10); + int result = randomNumber(1, 10); + int dividend = next * result; + operands.back() = dividend; // 修改被除数以确保整除 + operators.push_back('/'); + operands.push_back(next); + break; + } + } + return buildExpression(operands, operators); + } +}; + +// 初中题目生成器:生成初中级别的数学题目(包含平方和开方) +class MiddleQuestionGenerator : public MathQuestionGenerator { +public: + MiddleQuestionGenerator() {} + + // 生成指定范围内的随机数 + int randomNumber(int min, int max) { + return rand() % (max - min + 1) + min; + } + + // 生成初中题目:包含平方和开方运算 + std::string generateQuestion() override { + int operandCount = randomNumber(2, 5); + std::vector items; + bool hasSquareOrRoot = false; // 标记是否已包含平方或开方 + + // 生成操作数项 + for (int i = 0; i < operandCount; i++) { + int opType = randomNumber(0, 2); + // 确保至少有一个平方或开方运算 + if ((!hasSquareOrRoot && i == operandCount - 1) || (opType > 0 && !hasSquareOrRoot)) { + if (opType == 1) { + items.push_back(std::to_string(randomNumber(1, 100)) + "²"); // 平方 + } else { + items.push_back("√" + std::to_string(randomNumber(1, 100))); // 开方 + } + hasSquareOrRoot = true; + } else { + items.push_back(std::to_string(randomNumber(1, 100))); // 普通数字 + } + } + + // 生成运算符 + std::vector ops; + for (int i = 1; i < operandCount; i++) { + int opType = randomNumber(0, 3); + switch (opType) { + case 0: ops.push_back("+"); break; + case 1: ops.push_back("-"); break; + case 2: ops.push_back("*"); break; + case 3: ops.push_back("/"); break; + } + } + + // 找到可以加括号的位置(普通数字位置) + std::vector validIdx; + for (int i = 0; i < operandCount; i++) { + if (items[i].find("²") == std::string::npos && items[i].find("√") == std::string::npos) { + validIdx.push_back(i); + } + } + + // 随机选择括号位置 + int l = 0, r = 0; + if (validIdx.size() > 1) { + l = validIdx[rand() % (validIdx.size() - 1)]; + int range = validIdx.size() - (l + 1); + if (range == 0) { + r = l + 1; + } else { + r = l + 1 + rand() % range; + } + } + + // 构建表达式 + std::string expr; + for (int i = 0; i < operandCount; i++) { + if (i == l && validIdx.size() > 1) expr += "("; + expr += items[i]; + if (i == r && validIdx.size() > 1) expr += ")"; + if (i < ops.size()) expr += " " + ops[i] + " "; + } + + // 如果没有括号,给整个表达式加括号 + if (expr.find('(') == std::string::npos && validIdx.size() > 1) expr = "(" + expr + ")"; + return expr; + } +}; + +// 高中题目生成器:生成高中级别的数学题目(包含三角函数) +class HighQuestionGenerator : public MathQuestionGenerator { +public: + HighQuestionGenerator() {} + + // 生成指定范围内的随机数 + int randomNumber(int min, int max) { + return rand() % (max - min + 1) + min; + } + + // 生成高中题目:包含三角函数、平方和开方运算 + std::string generateQuestion() override { + int operandCount = randomNumber(2, 5); + std::vector items; + bool hasTrigonometry = false; // 标记是否已包含三角函数 + + // 生成操作数项 + for (int i = 0; i < operandCount; i++) { + int opType = randomNumber(0, 5); + // 确保至少有一个三角函数 + if ((!hasTrigonometry && i == operandCount - 1) || (opType >= 3 && !hasTrigonometry)) { + int trigType = randomNumber(0, 2); + switch (trigType) { + case 0: items.push_back("sin(" + std::to_string(randomNumber(1, 100)) + ")"); break; + case 1: items.push_back("cos(" + std::to_string(randomNumber(1, 100)) + ")"); break; + case 2: items.push_back("tan(" + std::to_string(randomNumber(1, 100)) + ")"); break; + } + hasTrigonometry = true; + } else if (opType == 1) { + items.push_back(std::to_string(randomNumber(1, 100)) + "²"); // 平方 + } else if (opType == 2) { + items.push_back("√" + std::to_string(randomNumber(1, 100))); // 开方 + } else { + items.push_back(std::to_string(randomNumber(1, 100))); // 普通数字 + } + } + + // 生成运算符 + std::vector ops; + for (int i = 1; i < operandCount; i++) { + int opType = randomNumber(0, 3); + switch (opType) { + case 0: ops.push_back("+"); break; + case 1: ops.push_back("-"); break; + case 2: ops.push_back("*"); break; + case 3: ops.push_back("/"); break; + } + } + + // 找到可以加括号的位置(非三角函数位置) + std::vector validIdx; + for (int i = 0; i < operandCount; i++) { + if (items[i].find("sin(") == std::string::npos && + items[i].find("cos(") == std::string::npos && + items[i].find("tan(") == std::string::npos) { + validIdx.push_back(i); + } + } + + // 随机选择括号位置 + int l = -1, r = -1; + if (validIdx.size() > 1) { + int idx1 = rand() % validIdx.size(); + int idx2; + do { + idx2 = rand() % validIdx.size(); + } while (idx1 == idx2); + + if (validIdx[idx1] < validIdx[idx2]) { + l = validIdx[idx1]; + r = validIdx[idx2]; + } else { + l = validIdx[idx2]; + r = validIdx[idx1]; + } + } + + // 构建表达式 + std::string expr; + for (int i = 0; i < operandCount; i++) { + if (i == l) expr += "("; + expr += items[i]; + if (i == r) expr += ")"; + if (i < ops.size()) expr += " " + ops[i] + " "; + } + return expr; + } +}; + +// 数学卷子生成主类:管理用户登录、题目生成、文件保存等核心功能 class MathPaperGenerator { private: - vector accounts; // 所有账户信息 - string currentUser; // 当前登录用户 - string currentType; // 当前题目类型 - bool isLoggedIn; // 登录状态 - map> userQuestions; // 用户已生成题目集合(防止重复) + vector accounts; // 存储所有账户信息 + string currentUser; // 当前登录用户 + string currentType; // 当前题目类型 + bool isLoggedIn; // 登录状态标记 + map> userQuestions; // 用户已生成题目记录(用于查重) + MathQuestionGenerator* questionGenerator; // 题目生成器指针 // 创建目录 bool createDirectory(const string& path) { @@ -68,7 +337,7 @@ private: return files; } - // 去除字符串首尾空白 + // 去除字符串首尾空白字符 string trim(const string& str) { size_t start = str.find_first_not_of(" \t\n\r"); size_t end = str.find_last_not_of(" \t\n\r"); @@ -78,44 +347,10 @@ private: return str.substr(start, end - start + 1); } - // 生成[min, max]范围的随机数 - int randomNumber(int min, int max) { - return rand() % (max - min + 1) + min; - } - -public: - // 构造函数,初始化账户并创建用户文件夹 - MathPaperGenerator() { - isLoggedIn = false; - currentUser = ""; - currentType = ""; - - accounts = { - {"张三1", "123", "小学"}, - {"张三2", "123", "小学"}, - {"张三3", "123", "小学"}, - {"李四1", "123", "初中"}, - {"李四2", "123", "初中"}, - {"李四3", "123", "初中"}, - {"王五1", "123", "高中"}, - {"王五2", "123", "高中"}, - {"王五3", "123", "高中"} - }; - - for (const auto& account : accounts) { - string folderPath = account.username; - if (!directoryExists(folderPath)) { - createDirectory(folderPath); - } - loadUserQuestions(account.username); - } - } - // 加载用户已生成题目(防止重复) void loadUserQuestions(const string& username) { userQuestions[username].clear(); string folderPath = username; - if (!directoryExists(folderPath)) { return; } @@ -139,307 +374,114 @@ public: } } } - - // 用户登录 - bool login(const string& username, const string& password) { - for (const auto& account : accounts) { - if (account.username == username && account.password == password) { - currentUser = username; - currentType = account.type; - isLoggedIn = true; - return true; - } - } - return false; - } - - // 注销 - void logout() { + +public: + // 构造函数:初始化账户、创建用户目录、加载历史题目 + MathPaperGenerator() { isLoggedIn = false; currentUser = ""; currentType = ""; - } - - // 切换题目类型 - bool switchType(const string& type) { - string trimmedType = trim(type); - if (trimmedType == "小学" || trimmedType == "初中" || trimmedType == "高中") { - currentType = trimmedType; - return true; - } - return false; - } - - // 生成小学题目(仅加减乘除) - string generatePrimaryQuestion() { - int operandCount = randomNumber(2, 5); - vector operands; - vector operators; - // 先生成第一个操作数 - operands.push_back(randomNumber(1, 100)); + // 初始化预设账户 + accounts = { + {"张三1", "123", "小学"}, + {"张三2", "123", "小学"}, + {"张三3", "123", "小学"}, + {"李四1", "123", "初中"}, + {"李四2", "123", "初中"}, + {"李四3", "123", "初中"}, + {"王五1", "123", "高中"}, + {"王五2", "123", "高中"}, + {"王五3", "123", "高中"} + }; - for (int i = 0; i < operandCount - 1; i++) { - int opType = randomNumber(0, 3); - int prev = operands.back(); - int next; - switch (opType) { - case 0: // 加法 - next = randomNumber(1, 100); - operators.push_back('+'); - operands.push_back(next); - break; - case 1: // 减法,保证前一个数大于等于后一个数 - next = randomNumber(1, prev); - operators.push_back('-'); - operands.push_back(next); - break; - case 2: // 乘法 - next = randomNumber(1, 100); - operators.push_back('*'); - operands.push_back(next); - break; - case 3: // 除法,保证能整除且结果为正整数 - { - // 先随机一个除数,不能为0 - next = randomNumber(1, 10); - int result = randomNumber(1, 10); - int dividend = next * result; - // dividend 作为前一个数,next 作为后一个数 - operands.back() = dividend; - operators.push_back('/'); - operands.push_back(next); - } - break; + // 创建用户目录并加载历史题目 + for (const auto& account : accounts) { + string folderPath = account.username; + if (!directoryExists(folderPath)) { + createDirectory(folderPath); } + loadUserQuestions(account.username); } - return buildExpression(operands, operators); + questionGenerator = nullptr; } - - // 生成初中题目(加减乘除+平方/根号) - string generateMiddleQuestion() { - int operandCount = randomNumber(2, 5); - vector operands; - vector operators; // 使用string以支持平方和根号 - - for (int i = 0; i < operandCount; i++) { - operands.push_back(randomNumber(1, 100)); - } - - // 确保至少有一个平方或根号 - bool hasSquareOrRoot = false; + + // 切换题目类型:小学/初中/高中 + bool switchType(const string& type) { + string trimmedType = trim(type); - // 构建表达式 - string expression = ""; - for (int i = 0; i < operandCount; i++) { - if (i > 0) { - int opType = randomNumber(0, 3); - switch (opType) { - case 0: expression += " + "; break; - case 1: expression += " - "; break; - case 2: expression += " * "; break; - case 3: expression += " / "; break; - } - } - - // 随机决定是否添加平方或根号(确保至少有一个) - int specialOp = randomNumber(0, 3); - if ((!hasSquareOrRoot && i == operandCount - 1) || (specialOp == 0 && i < operandCount - 1)) { - // 添加平方或根号 - if (randomNumber(0, 1) == 0) { - expression += to_string(operands[i]) + "²"; // 平方 - } else { - expression += "√" + to_string(operands[i]); // 根号 - } - hasSquareOrRoot = true; - } else { - expression += to_string(operands[i]); - } + // 清理旧的生成器 + if (questionGenerator) { + delete questionGenerator; + questionGenerator = nullptr; } - // 如果还没有平方或根号,强制添加一个 - if (!hasSquareOrRoot) { - int pos = randomNumber(0, operandCount - 1); - size_t numStart = 0; - for (int i = 0; i < pos; i++) { - size_t opPos = expression.find_first_of("+-*/", numStart); - if (opPos != string::npos) { - numStart = opPos + 3; // 跳过运算符和空格 - } - } - - // 在指定位置插入平方或根号 - if (randomNumber(0, 1) == 0) { - expression.insert(numStart, "("); - size_t insertPos = expression.find(' ', numStart); - if (insertPos == string::npos) { - insertPos = expression.size(); - } - expression.insert(insertPos, ")²"); - } else { - expression.insert(numStart, "√("); - size_t insertPos = expression.find(' ', numStart); - if (insertPos == string::npos) { - insertPos = expression.size(); - } - expression.insert(insertPos, ")"); - } + // 根据类型创建相应的题目生成器 + if (trimmedType == "小学") { + currentType = trimmedType; + questionGenerator = new PrimaryQuestionGenerator(); + return true; + } else if (trimmedType == "初中") { + currentType = trimmedType; + questionGenerator = new MiddleQuestionGenerator(); + return true; + } else if (trimmedType == "高中") { + currentType = trimmedType; + questionGenerator = new HighQuestionGenerator(); + return true; } - - return expression; + return false; } - - // 生成高中题目(加减乘除+平方/根号+三角函数) - string generateHighQuestion() { - int operandCount = randomNumber(2, 5); - vector operands; - - for (int i = 0; i < operandCount; i++) { - operands.push_back(randomNumber(1, 100)); - } - - // 确保至少有一个三角函数 - bool hasTrigonometry = false; - - // 构建表达式 - string expression = ""; - for (int i = 0; i < operandCount; i++) { - if (i > 0) { - int opType = randomNumber(0, 3); - switch (opType) { - case 0: expression += " + "; break; - case 1: expression += " - "; break; - case 2: expression += " * "; break; - case 3: expression += " / "; break; - } - } - - // 随机决定是否添加平方、根号或三角函数 - int specialOp = randomNumber(0, 5); - if ((!hasTrigonometry && i == operandCount - 1) || specialOp >= 2) { - // 添加特殊运算 - int opChoice = randomNumber(0, 4); - switch (opChoice) { - case 0: // 平方 - expression += to_string(operands[i]) + "²"; - break; - case 1: // 根号 - expression += "√" + to_string(operands[i]); - break; - case 2: // sin - expression += "sin(" + to_string(operands[i]) + ")"; - hasTrigonometry = true; - break; - case 3: // cos - expression += "cos(" + to_string(operands[i]) + ")"; - hasTrigonometry = true; - break; - case 4: // tan - expression += "tan(" + to_string(operands[i]) + ")"; - hasTrigonometry = true; - break; - } - } else { - expression += to_string(operands[i]); - } - } - - // 如果还没有三角函数,强制添加一个 - if (!hasTrigonometry) { - int pos = randomNumber(0, operandCount - 1); - size_t numStart = 0; - for (int i = 0; i < pos; i++) { - size_t opPos = expression.find_first_of("+-*/", numStart); - if (opPos != string::npos) { - numStart = opPos + 3; // 跳过运算符和空格 - } - } - - // 在指定位置插入三角函数 - int trigChoice = randomNumber(0, 2); - size_t insertPos; - switch (trigChoice) { - case 0: - expression.insert(numStart, "sin("); - insertPos = expression.find(' ', numStart); - if (insertPos == string::npos) { - insertPos = expression.size(); - } - expression.insert(insertPos, ")"); - break; - case 1: - expression.insert(numStart, "cos("); - insertPos = expression.find(' ', numStart); - if (insertPos == string::npos) { - insertPos = expression.size(); - } - expression.insert(insertPos, ")"); - break; - case 2: - expression.insert(numStart, "tan("); - insertPos = expression.find(' ', numStart); - if (insertPos == string::npos) { - insertPos = expression.size(); - } - expression.insert(insertPos, ")"); - break; + + // 用户登录验证 + bool login(const string& username, const string& password) { + for (const auto& account : accounts) { + if (account.username == username && account.password == password) { + currentUser = username; + currentType = account.type; + isLoggedIn = true; + switchType(currentType); // 根据用户类型初始化题目生成器 + return true; } } - - return expression; - } - - // 构建表达式 - string buildExpression(const vector& operands, const vector& operators) { - // 构建表达式,保证顺序与生成一致 - string expression = to_string(operands[0]); - for (size_t i = 0; i < operators.size(); i++) { - expression += " " + string(1, operators[i]) + " " + to_string(operands[i + 1]); - } - return expression; - } - - // 判断题目是否重复 - bool isQuestionDuplicate(const string& question) { - return userQuestions[currentUser].find(question) != userQuestions[currentUser].end(); + return false; } - - // 生成指定数量题目 + + // 生成指定数量的题目 vector generateQuestions(int count) { vector questions; - set generatedSet; + set generatedSet; // 本次生成题目的临时集合 int attempts = 0; - const int MAX_ATTEMPTS = count * 10; + const int MAX_ATTEMPTS = count * 10; // 最大尝试次数防止无限循环 + // 生成不重复的题目 while (questions.size() < count && attempts < MAX_ATTEMPTS) { string question; - - if (currentType == "小学") { - question = generatePrimaryQuestion(); - } else if (currentType == "初中") { - question = generateMiddleQuestion(); - } else if (currentType == "高中") { - question = generateHighQuestion(); + if (questionGenerator) { + question = questionGenerator->generateQuestion(); + } else { + question = ""; } + // 检查题目是否重复 if (!isQuestionDuplicate(question) && generatedSet.find(question) == generatedSet.end()) { questions.push_back(question); generatedSet.insert(question); - userQuestions[currentUser].insert(question); + userQuestions[currentUser].insert(question); // 添加到用户历史记录 } attempts++; } - // 如果无法生成足够的不重复题目,用简单题目填充 + // 如果无法生成足够的不重复题目,使用备用方案 while (questions.size() < count) { string question; if (currentType == "小学") { - question = to_string(randomNumber(1, 100)) + " + " + to_string(randomNumber(1, 100)); + question = to_string(rand() % 100 + 1) + " + " + to_string(rand() % 100 + 1); } else if (currentType == "初中") { - question = to_string(randomNumber(1, 100)) + "² + " + to_string(randomNumber(1, 100)); + question = to_string(rand() % 100 + 1) + "² + " + to_string(rand() % 100 + 1); } else { - question = "sin(" + to_string(randomNumber(1, 100)) + ") + " + to_string(randomNumber(1, 100)); + question = "sin(" + to_string(rand() % 100 + 1) + ") + " + to_string(rand() % 100 + 1); } if (!isQuestionDuplicate(question)) { @@ -450,102 +492,76 @@ public: return questions; } - - // 保存题目到文件 - void saveQuestions(const vector& questions) { - time_t now = time(nullptr); - tm* localTime = localtime(&now); - - stringstream filename; - filename << setfill('0') - << localTime->tm_year + 1900 << "-" - << setw(2) << localTime->tm_mon + 1 << "-" - << setw(2) << localTime->tm_mday << "-" - << setw(2) << localTime->tm_hour << "-" - << setw(2) << localTime->tm_min << "-" - << setw(2) << localTime->tm_sec << ".txt"; - - string filepath = currentUser + "/" + filename.str(); - ofstream file(filepath, ios::binary); - - if (file.is_open()) { - unsigned char bom[] = {0xEF, 0xBB, 0xBF}; - file.write((char*)bom, 3); - for (size_t i = 0; i < questions.size(); i++) { - string line = to_string(i + 1) + ". " + questions[i] + "\n"; - file.write(line.c_str(), line.size()); - if (i < questions.size() - 1) { - file.write("\n", 1); - } - } - file.close(); - cout << "题目已保存到: " << filepath << endl; - } else { - cout << "文件保存失败!" << endl; - } + + // 检查题目是否重复 + bool isQuestionDuplicate(const string& question) { + return userQuestions[currentUser].find(question) != userQuestions[currentUser].end(); + } + +private: + // 提示用户输入题目数量或切换类型 + void promptTypeAndCount() { + cout << endl << "准备生成" << currentType << "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)" << endl; + cout << "或者输入\"切换为小学/初中/高中\"来切换题目类型: "; } - // 处理用户输入 - void processInput() { - string input; - getline(cin, input); - - input = trim(input); - - if (input == "-1") { - logout(); - return; - } - - if (input.find("切换为") == 0) { - string type = input.substr(9); - type = trim(type); - - if (switchType(type)) { - cout << "切换成功!当前类型为:" << currentType << endl; - cout << "准备生成" << currentType << "数学题目,请输入生成题目数量: "; - getline(cin, input); - processCountInput(input); - } else { - cout << "请输入小学、初中和高中三个选项中的一个" << endl; - } - return; + // 处理类型切换命令 + void handleSwitchType(const string& type) { + if (switchType(type)) { + cout << "切换成功!当前类型为:" << currentType << endl; + promptTypeAndCount(); + string input; + getline(cin, input); + processCountInput(input); + } else { + cout << "请输入小学、初中和高中三个选项中的一个" << endl; } - - processCountInput(input); } - // 处理题目数量输入 - void processCountInput(const string& input) { - //* + // 处理数量输入 + void handleCountInput(const string& trimmedInput) { try { - //*/ - int count = stoi(input); + int count = stoi(trimmedInput); if (count >= 10 && count <= 30) { vector questions = generateQuestions(count); saveQuestions(questions); } else { cout << "题目数量应在10-30之间" << endl; } - //* } catch (const exception& e) { - cout << "请输入有效的数字" << endl; - } - //*/ - + cout << "请输入有效的数字或切换命令" << endl; + } } - // 主运行入口 + // 保存题目到文件 + void saveQuestionsToFile(const string& filepath, const vector& questions) { + ofstream file(filepath); + if (file.is_open()) { + for (size_t i = 0; i < questions.size(); i++) { + file << (i + 1) << ". " << questions[i]; + if (i < questions.size() - 1) file << "\n\n"; // 题目之间空一行 + } + file.close(); + cout << "题目已保存到: " << filepath << endl; + } else { + cout << "文件保存失败! 请检查目录权限。" << endl; + } + } + +public: + // 主运行循环:程序入口点 void run() { - srand(time(nullptr)); + srand(time(nullptr)); // 初始化随机数种子 + cout << "=== 中小学数学卷子自动生成程序 ===" << endl; while (true) { if (!isLoggedIn) { + // 登录流程 cout << "请输入用户名和密码(用空格隔开): "; string username, password; cin >> username >> password; - cin.ignore(); + cin.ignore(); // 清除输入缓冲区 if (login(username, password)) { cout << "登录成功!当前选择为" << currentType << "出题" << endl; @@ -555,18 +571,78 @@ public: } } + // 登录后的主循环 while (isLoggedIn) { - cout << endl << "准备生成" << currentType << "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)" << endl; - cout << "或者输入\"切换为小学/初中/高中\"来切换题目类型: "; + promptTypeAndCount(); processInput(); } } } + + // 处理用户输入 + void processInput() { + string input; + getline(cin, input); + input = trim(input); + + if (input == "-1") { + logout(); // 退出当前用户 + return; + } + + if (input.find("切换为") == 0) { + string type = input.substr(9); + type = trim(type); + handleSwitchType(type); + return; + } + + processCountInput(input); + } + + // 处理数量输入或切换命令 + void processCountInput(const string& input) { + string trimmedInput = trim(input); + + if (trimmedInput.find("切换为") == 0) { + string type = trimmedInput.substr(9); + type = trim(type); + handleSwitchType(type); + return; + } + + handleCountInput(trimmedInput); + } + + // 保存题目到文件(带时间戳的文件名) + void saveQuestions(const vector& questions) { + time_t now = time(nullptr); + tm* localTime = localtime(&now); + + stringstream filename; + filename << setfill('0') + << localTime->tm_year + 1900 << "-" + << setw(2) << localTime->tm_mon + 1 << "-" + << setw(2) << localTime->tm_mday << "-" + << setw(2) << localTime->tm_hour << "-" + << setw(2) << localTime->tm_min << "-" + << setw(2) << localTime->tm_sec << ".txt"; + + string filepath = currentUser + "/" + filename.str(); + saveQuestionsToFile(filepath, questions); + } + + // 注销当前用户 + void logout() { + isLoggedIn = false; + currentUser = ""; + currentType = ""; + } }; +// 程序主函数:创建生成器实例并启动程序 int main() { - MathPaperGenerator generator; - generator.run(); + generator.run(); // 启动主循环 return 0; } \ No newline at end of file diff --git a/src/main.exe b/src/main.exe index f0dbc68..3fa63a3 100644 Binary files a/src/main.exe and b/src/main.exe differ diff --git a/src/王五1/2025-09-29-19-09-07.txt b/src/王五1/2025-09-29-19-09-07.txt new file mode 100644 index 0000000..e91e77c --- /dev/null +++ b/src/王五1/2025-09-29-19-09-07.txt @@ -0,0 +1,59 @@ +1. (√77 + √72) - tan(30) + +2. (53² / 55 / sin(41) * √56 + 37²) + +3. tan(43) * 44 + +4. (52² + √30) / tan(57) + +5. (√67 + cos(58) / 57) * 59 + +6. cos(30) - 69 + +7. tan(53) + √10 + +8. √1 * sin(38) + +9. tan(24) + (35 + 40) + +10. sin(86) + 5 + +11. cos(100) / (√63 + 41) * 63 + +12. tan(48) * 100 - (90² + 16) * 39 + +13. √31 - cos(75) + +14. (74 - 69) + tan(28) + +15. (89 + 12) + sin(1) + +16. 85² + cos(77) * (27 / √35 / 56) + +17. sin(72) - 54 * (70 + 77) - 25 + +18. √49 / (√47 / cos(3) / 40) + +19. (57 / 7²) - cos(67) + +20. sin(11) / 63 + +21. sin(47) * (50 - √24) + +22. tan(15) * 25 + +23. 47 / cos(6) + +24. 3² / tan(39) + +25. (√12 / cos(19) + √29) + +26. sin(51) - (19 - √76) - 26 + +27. (√84 + √95) + sin(26) + +28. sin(67) - 13 + +29. cos(7) / 44 + (53 * √85) + +30. cos(4) / (46 / 13 / 85 * 25) \ No newline at end of file