Compare commits
9 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
59e273f93a | 4 months ago |
|
|
a2015d0259 | 4 months ago |
|
|
7da7dcf00b | 4 months ago |
|
|
5e5c1262a0 | 4 months ago |
|
|
f32da208b7 | 4 months ago |
|
|
eb827bce0d | 4 months ago |
|
|
eeffc11b73 | 4 months ago |
|
|
fa7ad43df3 | 4 months ago |
|
|
3643d6732f | 5 months ago |
@ -0,0 +1,2 @@
|
|||||||
|
# smath
|
||||||
|
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef HANSHU_H
|
||||||
|
#define HANSHU_H
|
||||||
|
|
||||||
|
#include "question.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 用户认证函数
|
||||||
|
User* AuthenticateUser(const std::string& username, const std::string& password);
|
||||||
|
bool IsValidUserType(const std::string& type);
|
||||||
|
|
||||||
|
// 文件操作函数
|
||||||
|
void SaveQuestionsToFile(const std::vector<std::string>& questions,
|
||||||
|
const std::string& username,
|
||||||
|
const std::string& type);
|
||||||
|
std::string GetCurrentTimestamp();
|
||||||
|
void CreateUserDirectory(const std::string& username);
|
||||||
|
|
||||||
|
// 输入验证函数
|
||||||
|
bool IsValidQuestionCount(int count);
|
||||||
|
bool IsSwitchCommand(const std::string& input, std::string& newtype);
|
||||||
|
|
||||||
|
// 系统流程函数
|
||||||
|
void DisplayWelcomeMessage();
|
||||||
|
void DisplayQuestionGenerator(std::unique_ptr<QuestionGenerator> generator,const User* users);
|
||||||
|
void DisplayCurrentMode(const std::string& type);
|
||||||
|
void DisplayQuestionExamples(const std::vector<std::string>& questions);
|
||||||
|
|
||||||
|
#endif // HANSHU_H
|
||||||
@ -0,0 +1,261 @@
|
|||||||
|
#include "question.h"
|
||||||
|
#include <stack>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// QuestionGenerator 基类实现
|
||||||
|
vector<string> QuestionGenerator::GenerateQuestion(int count) {
|
||||||
|
vector<string> questions;
|
||||||
|
int attempts = 0;
|
||||||
|
const int max_attempts = count * 10;
|
||||||
|
|
||||||
|
while (questions.size() < count && attempts < max_attempts) {
|
||||||
|
string question = GenerateLogic();
|
||||||
|
|
||||||
|
if (IsQuestionUnique(question)) {
|
||||||
|
questions.push_back(question);
|
||||||
|
existingqustions.insert(question);
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return questions;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QuestionGenerator::GetRand(int min, int max) {
|
||||||
|
|
||||||
|
uniform_int_distribution<> dis(min, max);
|
||||||
|
return dis(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
char QuestionGenerator::GetOperator() {
|
||||||
|
char operators[] = {'+', '-', '*', '/'};
|
||||||
|
return operators[GetRand(0, 3)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuestionGenerator::IsQuestionUnique(const string& question) const {
|
||||||
|
return existingqustions.find(question) == existingqustions.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuestionGenerator::ClearQuestions() {
|
||||||
|
existingqustions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrimaryQuestionGenerator 实现
|
||||||
|
string PrimaryQuestionGenerator::GenerateLogic() {
|
||||||
|
int operands = GetRand(2, 5);
|
||||||
|
|
||||||
|
// 50%概率使用带括号的表达式
|
||||||
|
if (GetRand(0, 1) == 1 && operands >= 3) {
|
||||||
|
return GenerateWithParentheses(operands);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成基础表达式
|
||||||
|
stringstream ss;
|
||||||
|
for (int i = 0; i < operands; i++) {
|
||||||
|
ss << GetRand(1, 100);
|
||||||
|
if (i < operands - 1) {
|
||||||
|
ss << " " << GetOperator() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimaryQuestionGenerator::GetType() const {
|
||||||
|
return "小学";
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimaryQuestionGenerator::ParenthesesCaceOne(int operands,
|
||||||
|
const vector<int>& numbers) {
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
ss << "(" << numbers[0] << " " << GetOperator() << " " << numbers[1] << ")";
|
||||||
|
|
||||||
|
for (int i = 2; i < operands; i++) {
|
||||||
|
ss << " " << GetOperator() << " " << numbers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimaryQuestionGenerator::ParenthesesCaceTwo(int operands,
|
||||||
|
const vector<int>& numbers) {
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
ss << numbers[0] << " " << GetOperator() << " ";
|
||||||
|
ss << "(" << numbers[1] << " " << GetOperator() << " " << numbers[2] << ")";
|
||||||
|
|
||||||
|
for (int i = 3; i < operands; i++) {
|
||||||
|
ss << " " << GetOperator() << " " << numbers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
string PrimaryQuestionGenerator::ParenthesesCaceThree(int operands,
|
||||||
|
const vector<int>& numbers) {
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
if (operands >= 4) {
|
||||||
|
int mid = operands / 2;
|
||||||
|
ss << "(";
|
||||||
|
for (int i = 0; i < mid; i++) {
|
||||||
|
if (i > 0) ss << " " << GetOperator() << " ";
|
||||||
|
ss << numbers[i];
|
||||||
|
}
|
||||||
|
ss << ") " << GetOperator() << " (";
|
||||||
|
for (int i = mid; i < operands; i++) {
|
||||||
|
if (i > mid) ss << " " << GetOperator() << " ";
|
||||||
|
ss << numbers[i];
|
||||||
|
}
|
||||||
|
ss << ")";
|
||||||
|
} else {
|
||||||
|
ss << "(" << numbers[0] << " " << GetOperator() << " " << numbers[1] << ")";
|
||||||
|
for (int i = 2; i < operands; i++) {
|
||||||
|
ss << " " << GetOperator() << " " << numbers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string PrimaryQuestionGenerator::GenerateWithParentheses(int operands) {
|
||||||
|
stringstream ss;
|
||||||
|
vector<int> numbers;
|
||||||
|
string result;
|
||||||
|
|
||||||
|
for (int i = 0; i < operands; i++) {
|
||||||
|
numbers.push_back(GetRand(1, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
int parenthesisType = GetRand(1, 3);
|
||||||
|
|
||||||
|
switch (parenthesisType) {
|
||||||
|
case 1:
|
||||||
|
result = ParenthesesCaceOne(operands,numbers);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
result = ParenthesesCaceTwo(operands,numbers);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
result = ParenthesesCaceThree(operands,numbers);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!IsValidParentheses(result)) {
|
||||||
|
return GenerateLogic(); // 重新生成
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrimaryQuestionGenerator::IsValidParentheses(const string& expr) const {
|
||||||
|
stack<char> st;
|
||||||
|
for (char c : expr) {
|
||||||
|
if (c == '(') st.push(c);
|
||||||
|
else if (c == ')') {
|
||||||
|
if (st.empty()) return false;
|
||||||
|
st.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return st.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// JuniorQuestionGenerator 实现
|
||||||
|
string JuniorQuestionGenerator::GenerateLogic() {
|
||||||
|
int operands = GetRand(1, 5);
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
for (int i = 0; i < operands; i++) {
|
||||||
|
if(i==0){
|
||||||
|
if (GetRand(0, 1) == 1) {
|
||||||
|
ss << GetRand(1, 20) << "^2";
|
||||||
|
} else {
|
||||||
|
ss << "√" << GetRand(1, 100);
|
||||||
|
}
|
||||||
|
if (i < operands - 1) {
|
||||||
|
ss << " " << GetOperator() << " ";
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
// 30%概率使用平方或开方
|
||||||
|
if (GetRand(0, 2) == 0) {
|
||||||
|
if (GetRand(0, 1) == 1) {
|
||||||
|
ss << GetRand(1, 20) << "^2";
|
||||||
|
} else {
|
||||||
|
ss << "√" << GetRand(1, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ss << GetRand(1, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < operands - 1) {
|
||||||
|
ss << " " << GetOperator() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string JuniorQuestionGenerator::GetType() const {
|
||||||
|
return "初中";
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeniorQuestionGenerator 实现
|
||||||
|
string SeniorQuestionGenerator::GenerateLogic() {
|
||||||
|
int operands = GetRand(1, 5);
|
||||||
|
stringstream ss;
|
||||||
|
|
||||||
|
for (int i = 0; i < operands; i++) {
|
||||||
|
if(i==0){
|
||||||
|
string trigFuncs[] = {"sin", "cos", "tan"};
|
||||||
|
string func = trigFuncs[GetRand(0, 2)];
|
||||||
|
ss << func << "(" << GetRand(1, 90) << ")";
|
||||||
|
if (i < operands - 1) {
|
||||||
|
ss << " " << GetOperator() << " ";
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 随机决定是否添加三角函数
|
||||||
|
if (GetRand(0, 2) == 0 ) {
|
||||||
|
string trigFuncs[] = {"sin", "cos", "tan"};
|
||||||
|
string func = trigFuncs[GetRand(0, 2)];
|
||||||
|
ss << func << "(" << GetRand(1, 90) << ")";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ss << GetRand(1, 100);
|
||||||
|
}
|
||||||
|
if (i < operands - 1) {
|
||||||
|
ss << " " << GetOperator() << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ss << " = ";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
string SeniorQuestionGenerator::GetType() const {
|
||||||
|
return "高中";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 工厂函数实现
|
||||||
|
unique_ptr<QuestionGenerator> CreateQuestionGenerator(const std::string& type) {
|
||||||
|
if (type == "小学") {
|
||||||
|
return make_unique<PrimaryQuestionGenerator>();
|
||||||
|
} else if (type == "初中") {
|
||||||
|
return make_unique<JuniorQuestionGenerator>();
|
||||||
|
} else if (type == "高中") {
|
||||||
|
return make_unique<SeniorQuestionGenerator>();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
#ifndef QUESTION_H
|
||||||
|
#define QUESTION_H
|
||||||
|
#include <chrono>
|
||||||
|
#include<set>
|
||||||
|
#include<string>
|
||||||
|
#include<vector>
|
||||||
|
#include<memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
std::string usertype;
|
||||||
|
};
|
||||||
|
//抽象基类
|
||||||
|
class QuestionGenerator{
|
||||||
|
protected:
|
||||||
|
std::set<std::string> existingqustions;//已生成的问题
|
||||||
|
std::mt19937 gen;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QuestionGenerator(){
|
||||||
|
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||||
|
gen.seed(static_cast<unsigned int>(seed));
|
||||||
|
}
|
||||||
|
virtual std::string GenerateLogic()=0;
|
||||||
|
virtual ~QuestionGenerator() = default;
|
||||||
|
virtual std::vector<std::string> GenerateQuestion(int count);//生成问题
|
||||||
|
virtual std::string GetType() const = 0;
|
||||||
|
int GetRand(int min,int max);//产生随机数字
|
||||||
|
char GetOperator();
|
||||||
|
bool IsQuestionUnique(const std::string& question) const;
|
||||||
|
void ClearQuestions();
|
||||||
|
|
||||||
|
};
|
||||||
|
//小学题目生成器
|
||||||
|
class PrimaryQuestionGenerator : public QuestionGenerator {
|
||||||
|
public:
|
||||||
|
PrimaryQuestionGenerator() = default;
|
||||||
|
std::string GenerateLogic() override;
|
||||||
|
std::string GetType() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string GenerateWithParentheses(int operands);
|
||||||
|
bool IsValidParentheses(const std::string& expr) const;
|
||||||
|
std::string ParenthesesCaceOne(int operands, const std::vector<int>& numbers);
|
||||||
|
std::string ParenthesesCaceTwo(int operands, const std::vector<int>& numbers);
|
||||||
|
std::string ParenthesesCaceThree(int operands, const std::vector<int>& numbers);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初中题目生成器
|
||||||
|
class JuniorQuestionGenerator : public QuestionGenerator {
|
||||||
|
public:
|
||||||
|
JuniorQuestionGenerator() = default;
|
||||||
|
std::string GenerateLogic() override;
|
||||||
|
std::string GetType() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 高中题目生成器
|
||||||
|
class SeniorQuestionGenerator : public QuestionGenerator {
|
||||||
|
public:
|
||||||
|
SeniorQuestionGenerator() = default;
|
||||||
|
std::string GenerateLogic() override;
|
||||||
|
std::string GetType() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 工厂函数声明
|
||||||
|
std::unique_ptr<QuestionGenerator> CreateQuestionGenerator(const std::string& type);
|
||||||
|
|
||||||
|
#endif // QUESTION_H
|
||||||
Loading…
Reference in new issue