luoyuehang 7 months ago
parent ea0b0f72ea
commit ec08b3bfaf

@ -0,0 +1,454 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <filesystem>
#include <cmath>
using namespace std;
// 用户账户结构
class User {
public:
string username;
string password;
string userType; // "小学", "初中", "高中"
};
// 题目生成接口
class QuestionGenerator {
public:
virtual string generateQuestion() = 0;
virtual bool meetsRequirements(const string& question) = 0;
virtual ~QuestionGenerator() {}
};
// 小学题目生成器
class PrimaryQuestionGenerator : public QuestionGenerator {
public:
string generateQuestion() override;
bool meetsRequirements(const string& question) override;
};
// 初中题目生成器
class JuniorQuestionGenerator : public QuestionGenerator {
public:
string generateQuestion() override;
bool meetsRequirements(const string& question) override;
};
// 高中题目生成器
class SeniorQuestionGenerator : public QuestionGenerator {
public:
string generateQuestion() override;
bool meetsRequirements(const string& question) override;
};
// 文件管理器类
class FileManager {
public:
static bool createUserFolder(const string& username);
static string generateFileName(const string& username);
static void saveQuestionsToFile(const string& filename, const vector<string>& questions);
static set<string> loadExistingQuestions(const string& username);
};
// 用户认证类
class UserAuthenticator {
private:
vector<User> presetUsers;
public:
UserAuthenticator();
bool authenticate(const string& username, const string& password, User& user);
};
// 应用程序主类
class MathTestGeneratorApp {
private:
User currentUser;
bool isLoggedIn;
set<string> generatedQuestions;
map<string, QuestionGenerator*> generators;
QuestionGenerator* currentGenerator;
public:
MathTestGeneratorApp();
~MathTestGeneratorApp();
void run();
void login();
void generatePaper();
void switchUserType(const string& newType);
bool isQuestionDuplicate(const string& question);
void addQuestionToHistory(const string& question);
string getCurrentTimeString();
};
// 预设账户
UserAuthenticator::UserAuthenticator() {
presetUsers = {
{"张三1", "123", "小学"},
{"张三2", "123", "小学"},
{"张三3", "123", "小学"},
{"李四1", "123", "初中"},
{"李四2", "123", "初中"},
{"李四3", "123", "初中"},
{"王五1", "123", "高中"},
{"王五2", "123", "高中"},
{"王五3", "123", "高中"}
};
}
bool UserAuthenticator::authenticate(const string& username, const string& password, User& user) {
for (const auto& u : presetUsers) {
if (u.username == username && u.password == password) {
user = u;
return true;
}
}
return false;
}
// 小学题目生成实现
string PrimaryQuestionGenerator::generateQuestion() {
int numOperands = rand() % 4 + 2; // 2-5个操作数
stringstream question;
vector<string> operators = {"+", "-", "*", "/"};
bool hasParentheses = (rand() % 2 == 0);
for (int i = 0; i < numOperands; i++) {
int operand = rand() % 100 + 1;
if (i == 0) {
if (hasParentheses && numOperands > 2 && rand() % 2 == 0) {
question << "(";
}
question << operand;
} else {
string op = operators[rand() % operators.size()];
question << " " << op << " " << operand;
if (hasParentheses && i == 1 && rand() % 2 == 0) {
question << ")";
}
}
}
question << " = ";
return question.str();
}
bool PrimaryQuestionGenerator::meetsRequirements(const string& question) {
// 小学题目只能包含 + - * / 和括号
for (char c : question) {
if (isalpha(c) && c != 's' && c != 'i' && c != 'n' && c != 'c' && c != 'o' && c != 't' && c != 'a') {
// 简单检查,实际需要更复杂的逻辑
continue;
}
}
return true;
}
// 初中题目生成实现
string JuniorQuestionGenerator::generateQuestion() {
int numOperands = rand() % 4 + 2; // 2-5个操作数
stringstream question;
vector<string> operators = {"+", "-", "*", "/", "²", ""};
bool hasSquareOrRoot = false;
for (int i = 0; i < numOperands; i++) {
int operand = rand() % 100 + 1;
if (i == 0) {
question << operand;
} else {
string op = operators[rand() % operators.size()];
if (op == "²") {
question << "² " << operators[rand() % 4] << " " << operand;
hasSquareOrRoot = true;
} else if (op == "") {
question << "" << operand << " " << operators[rand() % 4] << " " << operand;
hasSquareOrRoot = true;
} else {
question << " " << op << " " << operand;
}
}
}
// 确保至少有一个平方或开根号
if (!hasSquareOrRoot) {
int pos = rand() % numOperands;
// 简化处理,在实际应用中需要更复杂的逻辑
string temp = question.str();
size_t found = temp.find_last_of(" ");
if (found != string::npos) {
question.str("");
question << temp.substr(0, found) << "²" << temp.substr(found);
}
}
question << " = ";
return question.str();
}
bool JuniorQuestionGenerator::meetsRequirements(const string& question) {
// 检查是否包含平方或开根号
return question.find("²") != string::npos || question.find("") != string::npos;
}
// 高中题目生成实现
string SeniorQuestionGenerator::generateQuestion() {
int numOperands = rand() % 4 + 2; // 2-5个操作数
stringstream question;
vector<string> operators = {"+", "-", "*", "/", "sin", "cos", "tan"};
bool hasTrigonometry = false;
for (int i = 0; i < numOperands; i++) {
int operand = rand() % 100 + 1;
if (i == 0) {
if (rand() % 2 == 0) {
string trig = operators[4 + rand() % 3]; // sin, cos, tan
question << trig << "(" << operand << ")";
hasTrigonometry = true;
} else {
question << operand;
}
} else {
string op = operators[rand() % operators.size()];
if (op == "sin" || op == "cos" || op == "tan") {
question << " " << op << "(" << operand << ")";
hasTrigonometry = true;
} else {
question << " " << op << " " << operand;
}
}
}
// 确保至少有一个三角函数
if (!hasTrigonometry) {
string trig = operators[4 + rand() % 3];
int operand = rand() % 100 + 1;
question << " " << trig << "(" << operand << ")";
}
question << " = ";
return question.str();
}
bool SeniorQuestionGenerator::meetsRequirements(const string& question) {
// 检查是否包含三角函数
return question.find("sin") != string::npos ||
question.find("cos") != string::npos ||
question.find("tan") != string::npos;
}
// 文件管理实现
bool FileManager::createUserFolder(const string& username) {
try {
filesystem::create_directory(username);
return true;
} catch (...) {
return false;
}
}
string FileManager::generateFileName(const string& username) {
time_t now = time(0);
tm* localTime = localtime(&now);
stringstream ss;
ss << username << "/"
<< localTime->tm_year + 1900 << "-"
<< setw(2) << setfill('0') << localTime->tm_mon + 1 << "-"
<< setw(2) << setfill('0') << localTime->tm_mday << "-"
<< setw(2) << setfill('0') << localTime->tm_hour << "-"
<< setw(2) << setfill('0') << localTime->tm_min << "-"
<< setw(2) << setfill('0') << localTime->tm_sec << ".txt";
return ss.str();
}
void FileManager::saveQuestionsToFile(const string& filename, const vector<string>& questions) {
ofstream file(filename);
if (file.is_open()) {
for (size_t i = 0; i < questions.size(); i++) {
file << i + 1 << ". " << questions[i] << endl;
if (i < questions.size() - 1) {
file << endl; // 题目之间空一行
}
}
file.close();
}
}
set<string> FileManager::loadExistingQuestions(const string& username) {
set<string> questions;
// 简化实现,实际需要读取所有文件并提取题目
return questions;
}
// 应用程序实现
MathTestGeneratorApp::MathTestGeneratorApp() : isLoggedIn(false) {
generators["小学"] = new PrimaryQuestionGenerator();
generators["初中"] = new JuniorQuestionGenerator();
generators["高中"] = new SeniorQuestionGenerator();
currentGenerator = nullptr;
}
MathTestGeneratorApp::~MathTestGeneratorApp() {
for (auto& pair : generators) {
delete pair.second;
}
}
void MathTestGeneratorApp::run() {
srand(time(0));
while (true) {
if (!isLoggedIn) {
login();
} else {
cout << "准备生成" << currentUser.userType << "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录";
string input;
cin >> input;
if (input == "-1") {
isLoggedIn = false;
cout << "退出当前用户,重新登录..." << endl;
continue;
}
if (input.find("切换为") == 0) {
string newType = input.substr(3); // 跳过"切换为"
switchUserType(newType);
continue;
}
try {
int questionCount = stoi(input);
if (questionCount >= 10 && questionCount <= 30) {
generatePaper();
} else {
cout << "题目数量应在10-30之间" << endl;
}
} catch (const exception& e) {
cout << "请输入有效的数字" << endl;
}
}
}
}
void MathTestGeneratorApp::login() {
cout << "请输入用户名和密码(用空格隔开):";
string username, password;
cin >> username >> password;
UserAuthenticator authenticator;
if (authenticator.authenticate(username, password, currentUser)) {
isLoggedIn = true;
currentGenerator = generators[currentUser.userType];
cout << "当前选择为" << currentUser.userType << "出题" << endl;
// 加载已存在的题目用于查重
generatedQuestions = FileManager::loadExistingQuestions(currentUser.username);
} else {
cout << "请输入正确的用户名、密码" << endl;
}
}
void MathTestGeneratorApp::generatePaper() {
cout << "准备生成" << currentUser.userType << "数学题目,请输入生成题目数量:";
string input;
cin >> input;
try {
int questionCount = stoi(input);
if (questionCount < 10 || questionCount > 30) {
cout << "题目数量应在10-30之间" << endl;
return;
}
// 创建用户文件夹
FileManager::createUserFolder(currentUser.username);
// 生成题目
vector<string> questions;
for (int i = 0; i < questionCount; i++) {
string question;
int attempts = 0;
do {
question = currentGenerator->generateQuestion();
attempts++;
} while ((isQuestionDuplicate(question) || !currentGenerator->meetsRequirements(question)) && attempts < 100);
if (attempts >= 100) {
cout << "警告:无法生成符合要求的不重复题目" << endl;
}
questions.push_back(question);
addQuestionToHistory(question);
}
// 保存到文件
string filename = FileManager::generateFileName(currentUser.username);
FileManager::saveQuestionsToFile(filename, questions);
cout << "题目已生成到文件:" << filename << endl;
} catch (const exception& e) {
cout << "请输入有效的数字" << endl;
}
}
void MathTestGeneratorApp::switchUserType(const string& newType) {
if (newType == "小学" || newType == "初中" || newType == "高中") {
currentUser.userType = newType;
currentGenerator = generators[newType];
cout << "准备生成" << currentUser.userType << "数学题目,请输入生成题目数量:";
} else {
cout << "请输入小学、初中和高中三个选项中的一个" << endl;
}
}
bool MathTestGeneratorApp::isQuestionDuplicate(const string& question) {
return generatedQuestions.find(question) != generatedQuestions.end();
}
void MathTestGeneratorApp::addQuestionToHistory(const string& question) {
generatedQuestions.insert(question);
}
string MathTestGeneratorApp::getCurrentTimeString() {
time_t now = time(0);
tm* localTime = localtime(&now);
stringstream ss;
ss << localTime->tm_year + 1900 << "-"
<< setw(2) << setfill('0') << localTime->tm_mon + 1 << "-"
<< setw(2) << setfill('0') << localTime->tm_mday << "-"
<< setw(2) << setfill('0') << localTime->tm_hour << "-"
<< setw(2) << setfill('0') << localTime->tm_min << "-"
<< setw(2) << setfill('0') << localTime->tm_sec;
return ss.str();
}
int main() {
MathTestGeneratorApp app;
app.run();
return 0;
}
Loading…
Cancel
Save