四则运算出题器

一、目的:设计一个能够自动出题,并且自动完成答案核对,在最后给出所有题目的总答案》
二、实验人员:2352734,2352808
三、编译环境:DEV-C++。
四、运行代码:

点击查看代码 #include #include #include #include #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(std::rand()) / RAND_MAX * (max - min);
return static_cast(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;

}

// 输出所有题目和答案
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++写了一个"数学题自动出题器",我们试了一种叫"司机-领航员"的合作方式:司机:负责动手写代码,领航员:在旁边看着,随时提建议。这种合作写代码的方式真的很不错!一个人写代码容易钻牛角尖,两个人一起可以互相提醒。虽然有时候会有不同意见,但讨论后往往能找到更好的解决方法。做完这个程序,不仅学会了新技术,还体验到了团队合作的乐趣。

posted @ 2025-04-14 22:11  2352734  阅读(107)  评论(0)    收藏  举报