You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
7.0 KiB

#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;
}