parent
4f5b7c35fc
commit
22017b8b1f
@ -0,0 +1,60 @@
|
||||
#include "exam_manager.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <direct.h> // _mkdir (Windows)
|
||||
using namespace std;
|
||||
|
||||
static set<string> history;
|
||||
|
||||
ExamManager::ExamManager(QuestionGenerator* g, string folder)
|
||||
: generator(g), userFolder(folder) {
|
||||
// Windows 下创建目录(如果已存在则忽略)
|
||||
_mkdir(userFolder.c_str());
|
||||
}
|
||||
|
||||
void ExamManager::setGenerator(QuestionGenerator* g) {
|
||||
generator = g;
|
||||
}
|
||||
|
||||
bool ExamManager::checkDuplicate(const string& question) {
|
||||
return history.count(question) > 0;
|
||||
}
|
||||
|
||||
void ExamManager::generateExam(int numQuestions) {
|
||||
vector<string> questions;
|
||||
|
||||
for (int i = 0; i < numQuestions; i++) {
|
||||
string q;
|
||||
do {
|
||||
q = generator->generateQuestion();
|
||||
} while (checkDuplicate(q));
|
||||
|
||||
history.insert(q);
|
||||
questions.push_back(q);
|
||||
}
|
||||
|
||||
time_t now = time(0);
|
||||
tm ltm;
|
||||
localtime_s(<m, &now); // 安全版本
|
||||
|
||||
ostringstream filename;
|
||||
filename << userFolder << "/";
|
||||
filename << 1900 + ltm.tm_year << "-"
|
||||
<< 1 + ltm.tm_mon << "-"
|
||||
<< ltm.tm_mday << "-"
|
||||
<< ltm.tm_hour << "-"
|
||||
<< ltm.tm_min << "-"
|
||||
<< ltm.tm_sec << ".txt";
|
||||
|
||||
ofstream fout(filename.str());
|
||||
for (int i = 0; i < (int)questions.size(); i++) {
|
||||
fout << (i + 1) << ". " << questions[i] << "\n\n";
|
||||
}
|
||||
fout.close();
|
||||
|
||||
cout << "已生成试卷:" << filename.str() << endl;
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#ifndef EXAM_MANAGER_H
|
||||
#define EXAM_MANAGER_H
|
||||
|
||||
#include "question.h"
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
class ExamManager {
|
||||
private:
|
||||
QuestionGenerator* generator;
|
||||
string userFolder;
|
||||
public:
|
||||
ExamManager(QuestionGenerator* g, string folder);
|
||||
void setGenerator(QuestionGenerator* g);
|
||||
void generateExam(int numQuestions);
|
||||
bool checkDuplicate(const string& question);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,71 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include "user.h"
|
||||
#include "question.h"
|
||||
#include "exam_manager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
while (true) {
|
||||
string username, password;
|
||||
cout << "请输入用户名 密码 (输入 exit 退出程序): ";
|
||||
cin >> username;
|
||||
|
||||
if (username == "exit" || username == "退出") {
|
||||
cout << "程序已退出。" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cin >> password;
|
||||
|
||||
User* user = login(username, password);
|
||||
if (!user) {
|
||||
cout << "请输入正确的用户名、密码" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
cout << "当前选择为 " << user->getType() << " 出题" << endl;
|
||||
|
||||
QuestionGenerator* generator = nullptr;
|
||||
if (user->getType() == "小学") generator = new PrimaryGenerator();
|
||||
else if (user->getType() == "初中") generator = new JuniorGenerator();
|
||||
else generator = new SeniorGenerator();
|
||||
|
||||
ExamManager manager(generator, user->getName());
|
||||
|
||||
while (true) {
|
||||
cout << "准备生成 " << user->getType()
|
||||
<< " 数学题目,请输入生成题目数量"
|
||||
<< "(输入 -1 退出当前用户,输入 -2 退出程序):";
|
||||
|
||||
int n;
|
||||
cin >> n;
|
||||
|
||||
if (n == -2) {
|
||||
cout << "程序已退出。" << endl;
|
||||
delete generator;
|
||||
delete user;
|
||||
return 0; // 彻底退出
|
||||
}
|
||||
|
||||
if (n == -1) {
|
||||
cout << "已退出当前用户,请重新登录。" << endl;
|
||||
break; // 回到登录界面
|
||||
}
|
||||
|
||||
if (n < 10 || n > 30) {
|
||||
cout << "请输入 10-30 之间的数字!" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
manager.generateExam(n);
|
||||
}
|
||||
|
||||
delete generator;
|
||||
delete user;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
#include "question.h"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
static int randInt(int min, int max) {
|
||||
return min + rand() % (max - min + 1);
|
||||
}
|
||||
|
||||
// 小学:+ - * / ()
|
||||
string PrimaryGenerator::generateQuestion() {
|
||||
int n = randInt(2, 4);
|
||||
ostringstream oss;
|
||||
for (int i = 0; i < n; i++) {
|
||||
oss << randInt(1, 100);
|
||||
if (i != n - 1) {
|
||||
int op = randInt(0, 3);
|
||||
char ops[] = { '+', '-', '*', '/' };
|
||||
oss << " " << ops[op] << " ";
|
||||
}
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// 初中:至少含平方或开根号
|
||||
string JuniorGenerator::generateQuestion() {
|
||||
int n = randInt(2, 4);
|
||||
ostringstream oss;
|
||||
int specialPos = randInt(0, n - 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
int num = randInt(1, 20);
|
||||
if (i == specialPos) {
|
||||
if (randInt(0, 1))
|
||||
oss << num << "^2";
|
||||
else
|
||||
oss << "√" << num;
|
||||
}
|
||||
else {
|
||||
oss << randInt(1, 100);
|
||||
}
|
||||
if (i != n - 1) {
|
||||
int op = randInt(0, 3);
|
||||
char ops[] = { '+', '-', '*', '/' };
|
||||
oss << " " << ops[op] << " ";
|
||||
}
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// 高中:至少含 sin/cos/tan
|
||||
string SeniorGenerator::generateQuestion() {
|
||||
int n = randInt(2, 4);
|
||||
ostringstream oss;
|
||||
int specialPos = randInt(0, n - 1);
|
||||
vector<string> funcs = { "sin", "cos", "tan" };
|
||||
for (int i = 0; i < n; i++) {
|
||||
int num = randInt(1, 90);
|
||||
if (i == specialPos) {
|
||||
oss << funcs[randInt(0, 2)] << "(" << num << ")";
|
||||
}
|
||||
else {
|
||||
oss << randInt(1, 100);
|
||||
}
|
||||
if (i != n - 1) {
|
||||
int op = randInt(0, 3);
|
||||
char ops[] = { '+', '-', '*', '/' };
|
||||
oss << " " << ops[op] << " ";
|
||||
}
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
#ifndef QUESTION_H
|
||||
#define QUESTION_H
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
class QuestionGenerator {
|
||||
public:
|
||||
virtual string generateQuestion() = 0;
|
||||
virtual ~QuestionGenerator() {}
|
||||
};
|
||||
|
||||
class PrimaryGenerator : public QuestionGenerator {
|
||||
public:
|
||||
string generateQuestion() override;
|
||||
};
|
||||
|
||||
class JuniorGenerator : public QuestionGenerator {
|
||||
public:
|
||||
string generateQuestion() override;
|
||||
};
|
||||
|
||||
class SeniorGenerator : public QuestionGenerator {
|
||||
public:
|
||||
string generateQuestion() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,30 @@
|
||||
#include "user.h"
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
User::User(string u, string p, string t)
|
||||
: username(u), password(p), type(t) {
|
||||
}
|
||||
|
||||
string User::getName() const { return username; }
|
||||
string User::getType() const { return type; }
|
||||
|
||||
bool User::validate(const string& u, const string& p) const {
|
||||
return username == u && password == p;
|
||||
}
|
||||
|
||||
// 预设账户表
|
||||
static map<string, pair<string, string>> accounts = {
|
||||
{"张三1", {"123", "小学"}}, {"张三2", {"123", "小学"}}, {"张三3", {"123", "小学"}},
|
||||
{"李四1", {"123", "初中"}}, {"李四2", {"123", "初中"}}, {"李四3", {"123", "初中"}},
|
||||
{"王五1", {"123", "高中"}}, {"王五2", {"123", "高中"}}, {"王五3", {"123", "高中"}}
|
||||
};
|
||||
|
||||
User* login(const string& u, const string& p) {
|
||||
if (accounts.find(u) != accounts.end()) {
|
||||
if (accounts[u].first == p) {
|
||||
return new User(u, p, accounts[u].second);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
#ifndef USER_H
|
||||
#define USER_H
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
class User {
|
||||
private:
|
||||
string username;
|
||||
string password;
|
||||
string type; // 小学/初中/高中
|
||||
public:
|
||||
User(string u, string p, string t);
|
||||
string getName() const;
|
||||
string getType() const;
|
||||
bool validate(const string& u, const string& p) const;
|
||||
};
|
||||
|
||||
User* login(const string& u, const string& p);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in new issue