生成随机瞳孔数学问题

时间:2017-06-11 01:10:03

标签: c++ math

我尝试使用c ++为孩子们建立一个练习数学的程序。问题应该包括加法,减法,乘法和除法。这10个问题是随机产生的。此外,随机生成问题的数字。但是,必须确保问题和结果都不超过两位数。问题和结果应该大于或等于零。除数不能为零。

遵循我的工具。

        while(prob_cout < 10){
            int op = rand() % 4; // range 0-3 to match a operation
            int answer, userGuess;
            if (op == 0) { // addition
                int number1 = rand() % 100; // problem no langer than two digits 
                int number2 = rand() % 100;  // range 0-99 
                answer = number1 + number2;
                if (answer >= 0 && answer < 100) { // valid problem: result also no more than two digits
                    prob_cout++;
                    cout << number1 << " + " << number2 << " = ";
                    cin >> userGuess;
                    // record problem info
                    prob_record.push_back(number1);
                    prob_record.push_back(op);
                    prob_record.push_back(number2);
                    prob_record.push_back(answer);
                    prob_record.push_back(userGuess);
                    // check answer
                    if (answer == userGuess)
                        user_scores += 10;
                    else
                        continue;
                }
                else
                    continue;
            }
            else if(op == 1) { // subtraction
                int number1 = rand() % 100; // problem no langer than two digits 
                int number2 = rand() % 100;  // range 0-99 
                answer = number1 - number2;
                if (answer >= 0 && answer < 100) { // valid problem: result also no more than two digits
                    prob_cout++;
                    cout << number1 << " - " << number2 << " = ";
                    cin >> userGuess;
                    // record problem info
                    prob_record.push_back(number1);
                    prob_record.push_back(op);
                    prob_record.push_back(number2);
                    prob_record.push_back(answer);
                    prob_record.push_back(userGuess);
                    if (answer == userGuess)
                        user_scores += 10;
                    else
                        continue;
                }
                else
                    continue;
            }
            else if (op == 2) { // multiplication
                int number1 = rand() % 20; 
                int number2 = rand() % 20;   
                answer = number1 * number2;
                if (answer >= 0 && answer < 100) { // valid problem: result also no more than two digits
                    prob_cout++;
                    cout << number1 << " * " << number2 << " = ";
                    cin >> userGuess;
                    // record problem info
                    prob_record.push_back(number1);
                    prob_record.push_back(op);
                    prob_record.push_back(number2);
                    prob_record.push_back(answer);
                    prob_record.push_back(userGuess);
                    // check answer
                    if (answer == userGuess)
                        user_scores += 10;
                    else
                        continue;
                }
                else
                    continue;
            }
            else if (op == 3) { //dividion
                int number1 = rand() % 100; 
                int number2 = rand() % 50; 
                answer = number1 / number2;
                if (answer >= 0 && answer < 100 && number1 > number2) { // valid problem: result also no more than two digits
                    prob_cout++;
                    cout << number1 << " / " << number2 << " = ";
                    cin >> userGuess;
                    // record problem info
                    prob_record.push_back(number1);
                    prob_record.push_back(op);
                    prob_record.push_back(number2);
                    prob_record.push_back(answer);
                    prob_record.push_back(userGuess);
                    // check answer
                    if (answer == userGuess)
                        user_scores += 10;
                    else
                        continue;
                }
                else
                    continue;
            }
        }

但是。我发现这种方法无法确保这四种操作具有相同的可能性。加法和减法不仅仅是乘法和除法!

任何人都有更好的主意吗?

2 个答案:

答案 0 :(得分:1)

我很想找到一种数学方法来确保所选择的值在可接受的范围内。

这样的事情:

#include <iostream>
#include <random>
#include <string>

int random_number(int from, int to)
{
    thread_local static std::mt19937 mt{std::random_device{}()};
    return std::uniform_int_distribution<int>{from, to}(mt);
}

int main()
{
    std::string const ops = "+-*/";

    for(auto n = 0; n < 10; ++n)
    {
        int lhs;
        int rhs;

        auto op = ops[random_number(0, 3)];

        switch(op)
        {
            case '+':
                lhs = random_number(0, 99);
                rhs = random_number(0, 99 - lhs);
                if(random_number(0, 1))
                    std::swap(lhs, rhs);
                break;

            case '-':
                lhs = random_number(0, 99);
                rhs = random_number(0, lhs);
                break;

            case '*':
                lhs = random_number(1, 99);
                rhs = random_number(0, 99 / lhs);
                if(random_number(0, 1))
                    std::swap(lhs, rhs);
                break;

            case '/':
                rhs = random_number(1, 10);
                lhs = rhs * random_number(0, 10);
                break;
        }

        std::cout << (n < 9 ? " ":"") << (n + 1);
        std::cout << ": " << (lhs < 10 ? " ":"") << lhs;
        std::cout << " " << op;
        std::cout << " " << (rhs < 10 ? " ":"") << rhs;
        std::cout << " = " << '\n';
    }
}

示例输出:

 1:  1 * 27 = 
 2: 12 /  2 = 
 3:  1 + 94 = 
 4: 87 - 63 = 
 5:  1 -  1 = 
 6:  9 *  6 = 
 7: 39 - 39 = 
 8: 47 + 33 = 
 9: 21 /  3 = 
10: 49 + 48 = 

答案 1 :(得分:0)

问题要求,例如if(answer >= 0 && answer < 100),加法和减法比乘法和除法更容易满足。这就是为什么后来者的问题被拒绝了。

如果您希望这些操作的份额几乎相等,则一个简单的解决方法是不在每个循环中再次选择运算符,而是保持相同的运算符并再次尝试,直到同一运算符出现可接受的问题。

为此,首先将运算符初始化为某个值,例如-1,仅在这种情况下添加选择新运算符。另一方面,当已经选择的运算符拒绝问题时,您不会选择新的运算符。只有在问题生成并被接受时,您才会设置op = -1,恰好靠近您设置的每个地方prob_cout++;

整体结构如下:

int op = -1;
while(prob_cout < 10){
        if(op == -1) op = rand() % 4; // <-- dont select a new operation when op already selected
        int answer, userGuess;
        if (op == 0) { // addition
        // generate addition problem
        if (answer >= 0 && answer < 100) { // valid problem                   
        prob_cout++;
        op = -1; // <----- so that next iteration an new operator is randomly selected.
       // Place op = -1 near each prob_cout++ statement in your initial code.

请注意,这是一个解决(快速)平衡不同运营商频率问题的建议。但是,我认为,从代码质量的角度来看,您的代码还有改进的余地,因为它有很多重复的操作,可以通过某种方式进行分解。但这是另一个话题。