四则运算出题器
一、目的:设计一个能够自动出题,并且自动完成答案核对,在最后给出所有题目的总答案》
二、实验人员:2352734,2352808
三、编译环境:DEV-C++。
四、运行代码:
点击查看代码
#include// 生成随机整数
int generateRandomNumber(int min, int max) {
if (min > max) {
std::cerr << "Error: min should be less than or equal to max." << std::endl;
return -1;
}
return min + std::rand() % (max - min + 1);
}
// 生成随机小数,保留两位小数
double generateRandomDouble(double min, double max) {
if (min > max) {
std::cerr << "Error: min should be less than or equal to max." << std::endl;
return -1.0;
}
double num = min + static_cast
return static_cast
}
// 加法运算
double addition(double a, double b) {
return a + b;
}
// 减法运算
double subtraction(double a, double b) {
return a - b;
}
// 乘法运算
double multiplication(double a, double b) {
return a * b;
}
// 除法运算
double division(double a, double b) {
if (b == 0) {
std::cerr << "Error: division by zero." << std::endl;
return -1.0;
}
return a / b;
}
// 计算混合表达式结果
double calculateMixedExpression(double a, double b, double c, double d, double e) {
if (e == 0) {
std::cerr << "Error: division by zero in mixed expression." << std::endl;
return -1.0;
}
// 计算 (a + b) * c - d / e
double firstPart = (a + b) * c;
double secondPart = d / e;
return firstPart - secondPart;
}
// 生成随机四则运算表达式
void generateArithmeticExpression(double* answers, int index, int difficulty) {
double a, b, c, d, e;
double result;
int questionType = generateRandomNumber(1, 7);
int maxInt = (difficulty == 1) ? 10 : (difficulty == 2) ? 50 : 100;
double maxDouble = (difficulty == 1) ? 10.0 : (difficulty == 2) ? 50.0 : 100.0;
switch (questionType) {
case 1: // 整数加法
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, maxInt);
result = addition(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " + " << static_cast<int>(b) << " = " << std::endl;
break;
case 2: // 整数减法
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, static_cast<int>(a));
result = subtraction(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " - " << static_cast<int>(b) << " = " << std::endl;
break;
case 3: // 整数乘法
a = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
b = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
result = multiplication(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " * " << static_cast<int>(b) << " = " << std::endl;
break;
case 4: // 整数除法
do {
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
} while (static_cast<int>(a) % static_cast<int>(b) != 0);
result = division(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " / " << static_cast<int>(b) << " = " << std::endl;
break;
case 5: // 混合运算
do {
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, maxInt);
c = generateRandomNumber(1, maxInt);
d = generateRandomNumber(1, maxInt);
// 确保除法不会出现小数
e = generateRandomNumber(1, maxInt);
while (static_cast<int>(d) % static_cast<int>(e) != 0) {
d = generateRandomNumber(1, maxInt);
e = generateRandomNumber(1, maxInt);
}
result = calculateMixedExpression(a, b, c, d, e);
} while (result < 0 || result > ((difficulty == 1) ? 100 : (difficulty == 2) ? 300 : 500));
std::cout << "第 " << index + 1 << " 题: (" << static_cast<int>(a) << " + " << static_cast<int>(b) << ") * " << static_cast<int>(c) << " - " << static_cast<int>(d) << " / " << static_cast<int>(e) << " = " << std::endl;
break;
case 6: // 小数加法
a = generateRandomDouble(1.0, maxDouble);
b = generateRandomDouble(1.0, maxDouble);
result = addition(a, b);
std::cout << "第 " << index + 1 << " 题: " << std::fixed << std::setprecision(2) << a << " + " << b << " = " << std::endl;
break;
case 7: // 小数减法
a = generateRandomDouble(1.0, maxDouble);
b = generateRandomDouble(1.0, a);
result = subtraction(a, b);
std::cout << "第 " << index + 1 << " 题: " << std::fixed << std::setprecision(2) << a << " - " << b << " = " << std::endl;
break;
default:
std::cerr << "Error: Invalid question type." << std::endl;
break;
}
answers[index] = result;
}
// 输出所有题目和答案
void printAllAnswers(double* answers, int numExpressions) {
std::cout << "\n所有题目的正确答案如下:" << std::endl;
for (int i = 0; i < numExpressions; ++i) {
std::cout << "第 " << i + 1 << " 题答案: " << std::fixed << std::setprecision(2) << answers[i] << std::endl;
}
}
int main() {
int numExpressions;
int difficulty;
// 选择题目数量
do {
std::cout << "请输入题目数量(5 - 20):";
while (!(std::cin >> numExpressions)) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (numExpressions < 5 || numExpressions > 20) {
std::cerr << "题目数量必须在 5 到 20 之间,请重新输入。" << std::endl;
}
} while (numExpressions < 5 || numExpressions > 20);
// 选择难度级别
do {
std::cout << "请选择难度级别(1 - 简单,2 - 中等,3 - 困难):";
while (!(std::cin >> difficulty)) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (difficulty < 1 || difficulty > 3) {
std::cerr << "难度级别必须是 1、2 或 3,请重新输入。" << std::endl;
}
} while (difficulty < 1 || difficulty > 3);
double userAnswers[20];
double correctAnswers[20];
// 初始化随机数种子
std::srand(static_cast<unsigned int>(std::time(nullptr)));
// 生成指定数量的随机四则运算表达式
std::cout << "以下是 " << numExpressions << " 个四则运算问题,请先查看题目,之后输入答案:" << std::endl;
for (int i = 0; i < numExpressions; ++i) {
generateArithmeticExpression(correctAnswers, i, difficulty);
}
// 记录开始时间
std::clock_t start = std::clock();
// 让用户输入答案
std::cout << "\n请依次输入上述 " << numExpressions << " 道题目的答案,输入 -1 可中途放弃:" << std::endl;
for (int i = 0; i < numExpressions; ++i) {
std::cout << "第 " << i + 1 << " 题答案: ";
while (!(std::cin >> userAnswers[i])) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (userAnswers[i] == -1) {
std::cout << "你已中途放弃测验。" << std::endl;
printAllAnswers(correctAnswers, numExpressions);
return 0;
}
}
// 记录结束时间
std::clock_t end = std::clock();
double elapsedTime = static_cast<double>(end - start) / CLOCKS_PER_SEC;
// 输出正确答案和得分
std::cout << "\n正确答案如下:" << std::endl;
int score = 0;
for (int i = 0; i < numExpressions; ++i) {
std::cout << "第 " << i + 1 << " 题:正确答案是 " << std::fixed << std::setprecision(2) << correctAnswers[i] << ", 你的答案是 " << userAnswers[i];
if (userAnswers[i] == correctAnswers[i]) {
std::cout << ",回答正确!" << std::endl;
score++;
} else {
std::cout << ",回答错误!" << std::endl;
}
}
std::cout << "\n你的最终得分是:" << score << " 分。" << std::endl;
std::cout << std::fixed << std::setprecision(2);
std::cout << "你完成测验所用的时间是:" << elapsedTime << " 秒。" << std::endl;
return 0;
}
五、功能分析
(1) 随机题目生成
支持7种不同类型的题目:
整数加法(1-100之间的数)
整数减法(确保结果为正)
整数乘法(1-10之间的数)
整数除法(确保能整除,被除数不为0)
混合运算(形式为 (a + b) * c - d / e,确保能整除且结果在0-500之间)
小数加法(1.0-100.0之间的数,保留两位小数)
小数减法(确保结果为正)
点击查看代码
// 生成随机整数
int generateRandomNumber(int min, int max) {
if (min > max) {
std::cerr << "Error: min should be less than or equal to max." << std::endl;
return -1;
}
return min + std::rand() % (max - min + 1);
}
// 生成随机小数,保留两位小数
double generateRandomDouble(double min, double max) {
if (min > max) {
std::cerr << "Error: min should be less than or equal to max." << std::endl;
return -1.0;
}
double num = min + static_cast<double>(std::rand()) / RAND_MAX * (max - min);
return static_cast<int>(num * 100) / 100.0;
}
// 加法运算
double addition(double a, double b) {
return a + b;
}
// 减法运算
double subtraction(double a, double b) {
return a - b;
}
// 乘法运算
double multiplication(double a, double b) {
return a * b;
}
// 除法运算
double division(double a, double b) {
if (b == 0) {
std::cerr << "Error: division by zero." << std::endl;
return -1.0;
}
return a / b;
}
// 计算混合表达式结果
double calculateMixedExpression(double a, double b, double c, double d, double e) {
if (e == 0) {
std::cerr << "Error: division by zero in mixed expression." << std::endl;
return -1.0;
}
// 计算 (a + b) * c - d / e
double firstPart = (a + b) * c;
double secondPart = d / e;
return firstPart - secondPart;
}
// 生成随机四则运算表达式
void generateArithmeticExpression(double* answers, int index, int difficulty) {
double a, b, c, d, e;
double result;
int questionType = generateRandomNumber(1, 7);
int maxInt = (difficulty == 1) ? 10 : (difficulty == 2) ? 50 : 100;
double maxDouble = (difficulty == 1) ? 10.0 : (difficulty == 2) ? 50.0 : 100.0;
switch (questionType) {
case 1: // 整数加法
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, maxInt);
result = addition(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " + " << static_cast<int>(b) << " = " << std::endl;
break;
case 2: // 整数减法
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, static_cast<int>(a));
result = subtraction(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " - " << static_cast<int>(b) << " = " << std::endl;
break;
case 3: // 整数乘法
a = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
b = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
result = multiplication(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " * " << static_cast<int>(b) << " = " << std::endl;
break;
case 4: // 整数除法
do {
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, (difficulty == 1) ? 5 : (difficulty == 2) ? 8 : 10);
} while (static_cast<int>(a) % static_cast<int>(b) != 0);
result = division(a, b);
std::cout << "第 " << index + 1 << " 题: " << static_cast<int>(a) << " / " << static_cast<int>(b) << " = " << std::endl;
break;
case 5: // 混合运算
do {
a = generateRandomNumber(1, maxInt);
b = generateRandomNumber(1, maxInt);
c = generateRandomNumber(1, maxInt);
d = generateRandomNumber(1, maxInt);
// 确保除法不会出现小数
e = generateRandomNumber(1, maxInt);
while (static_cast<int>(d) % static_cast<int>(e) != 0) {
d = generateRandomNumber(1, maxInt);
e = generateRandomNumber(1, maxInt);
}
result = calculateMixedExpression(a, b, c, d, e);
} while (result < 0 || result > ((difficulty == 1) ? 100 : (difficulty == 2) ? 300 : 500));
std::cout << "第 " << index + 1 << " 题: (" << static_cast<int>(a) << " + " << static_cast<int>(b) << ") * " << static_cast<int>(c) << " - " << static_cast<int>(d) << " / " << static_cast<int>(e) << " = " << std::endl;
break;
case 6: // 小数加法
a = generateRandomDouble(1.0, maxDouble);
b = generateRandomDouble(1.0, maxDouble);
result = addition(a, b);
std::cout << "第 " << index + 1 << " 题: " << std::fixed << std::setprecision(2) << a << " + " << b << " = " << std::endl;
break;
case 7: // 小数减法
a = generateRandomDouble(1.0, maxDouble);
b = generateRandomDouble(1.0, a);
result = subtraction(a, b);
std::cout << "第 " << index + 1 << " 题: " << std::fixed << std::setprecision(2) << a << " - " << b << " = " << std::endl;
break;
default:
std::cerr << "Error: Invalid question type." << std::endl;
break;
}
answers[index] = result;
}

(2) 难度分级
三个难度级别:
简单(1):数字范围小(1-10),乘法限制在 1-5。
中等(2):数字范围中等(1-50),乘法限制在 1-8。
困难(3):数字范围大(1-100),乘法限制在 1-10。
点击查看代码
// 选择难度级别
do {
std::cout << "请选择难度级别(1 - 简单,2 - 中等,3 - 困难):";
while (!(std::cin >> difficulty)) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (difficulty < 1 || difficulty > 3) {
std::cerr << "难度级别必须是 1、2 或 3,请重新输入。" << std::endl;
}
} while (difficulty < 1 || difficulty > 3);
double userAnswers[20];
double correctAnswers[20];



(3) 自定义题目数量
用户可输入 5 到 20 道题目,程序会动态生成对应数量的不相同的题目。
点击查看代码
int main() {
int numExpressions;
int difficulty;
// 选择题目数量
do {
std::cout << "请输入题目数量(5 - 20):";
while (!(std::cin >> numExpressions)) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (numExpressions < 5 || numExpressions > 20) {
std::cerr << "题目数量必须在 5 到 20 之间,请重新输入。" << std::endl;
}
} while (numExpressions < 5 || numExpressions > 20);
// 初始化随机数种子
std::srand(static_cast<unsigned int>(std::time(nullptr)));
// 生成指定数量的随机四则运算表达式
std::cout << "以下是 " << numExpressions << " 个四则运算问题,请先查看题目,之后输入答案:" << std::endl;
for (int i = 0; i < numExpressions; ++i) {
generateArithmeticExpression(correctAnswers, i, difficulty);
}


(4)答题阶段:
用户逐题输入答案,支持输入 -1 中途退出,且退出后会给出所有题目答案。
点击查看代码
std::cout << "\n请依次输入上述 " << numExpressions << " 道题目的答案,输入 -1 可中途放弃:" << std::endl;
for (int i = 0; i < numExpressions; ++i) {
std::cout << "第 " << i + 1 << " 题答案: ";
while (!(std::cin >> userAnswers[i])) {
std::cerr << "Error: Invalid input. Please enter a valid number." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if (userAnswers[i] == -1) {
std::cout << "你已中途放弃测验。" << std::endl;
printAllAnswers(correctAnswers, numExpressions);
return 0;
}
}

(5)得分和计时
点击查看代码
// 记录结束时间
std::clock_t end = std::clock();
double elapsedTime = static_cast<double>(end - start) / CLOCKS_PER_SEC;
// 输出正确答案和得分
std::cout << "\n正确答案如下:" << std::endl;
int score = 0;
for (int i = 0; i < numExpressions; ++i) {
std::cout << "第 " << i + 1 << " 题:正确答案是 " << std::fixed << std::setprecision(2) << correctAnswers[i] << ", 你的答案是 " << userAnswers[i];
if (userAnswers[i] == correctAnswers[i]) {
std::cout << ",回答正确!" << std::endl;
score++;
} else {
std::cout << ",回答错误!" << std::endl;
}
}
std::cout << "\n你的最终得分是:" << score << " 分。" << std::endl;
std::cout << std::fixed << std::setprecision(2);
std::cout << "你完成测验所用的时间是:" << elapsedTime << " 秒。" << std::endl;
return 0;
}

(6)输入错误符号时会提醒

六、实验过程中的问题:1.在多次运行程序时,由于随机种子基于时间,短时间内可能生成相同题目序列。
2.用户输入非数字时(如字母),程序会进入无限循环。
3.用户输入 0.1 + 0.2 的答案应为 0.3,但程序可能因浮点数精度误差判定为错误。
4.必须能整除,导致有些题出不来。
七、实验体会:我们两个人一起用C++写了一个"数学题自动出题器",我们试了一种叫"司机-领航员"的合作方式:司机:负责动手写代码,领航员:在旁边看着,随时提建议。这种合作写代码的方式真的很不错!一个人写代码容易钻牛角尖,两个人一起可以互相提醒。虽然有时候会有不同意见,但讨论后往往能找到更好的解决方法。做完这个程序,不仅学会了新技术,还体验到了团队合作的乐趣。

浙公网安备 33010602011771号