生成随机学生数学问题
Generate random pupil math problems
我尝试使用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;
}
}
但。我发现这种方法不能确保这四种操作的同等可能性。加法和减法不仅仅是乘法和除法!
有人有更好的主意吗?
我很想找到一种数学方法来确保选择的值在可接受的范围内。
像这样:
#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 =
问题要求,如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.
请注意,这是一个建议,以(快速)解决平衡不同运营商的频率问题。但是,我认为从代码质量的角度来看,您的代码还有改进的余地,因为它有很多可以以某种方式分解的重复操作。但这是另一个话题。
相关文章:
- 在类中使用随机生成器时出现性能问题
- 代码输出随机符号,我不确定出了什么问题
- 这个随机字符串打印代码有什么问题?
- 我在理解 AVX 随机内部函数如何为 8 位时遇到一些问题
- C++ 制作一个随机数字/字母生成器,代码中有问题
- C++ 随机套牌问题
- 生成随机学生数学问题
- 随机化问题
- 再次随机化的问题
- 按行、列或随机从数组填充矩阵时出现错误索引问题
- 随机树CvRTrees持久性问题opencv
- 在C++中使用std::ofstream创建具有随机文件名的文件时出现问题
- 使用快速英特尔随机生成器(SSE2)会因堆栈问题而失败..已损坏
- 如何随机排列数组问题
- 使用梅森捻线机随机双生成的性能问题
- 随机化不会在 while 循环中发生。如何解决这个问题?C++
- 定义的随机问题
- 我在生成两副单独随机的纸牌时遇到问题
- 在matlab上生成有限制的随机向量时出现问题
- 我无法弄清楚这个随机发生器有什么问题