一种基于分支算法的小学连续口算题目生成及作答程序
与学号2352116的同学一同完成
程序要求:
不限方式实现生成随机两次运算的口算题生成,限制如下:
1.不出现小数
2.运算结果范围为0-1000
3.每个算数不大于100
附加的功能是实时计算正确率。
首先把完整的代码放上来,但是这个代码的逻辑其实挺傻瓜的。
点击查看代码
#include <iostream>
#include <cstdlib>
#include <ctime> // 用于 srand(time(0))
using namespace std;
int correct_count = 0;
int incorrect_count = 0;
class formula {
private:
int first_number;
int first_sign;
int second_number;
int second_sign;
int third_number;
bool is_legal;
public:
formula() {
first_number = 0;
first_sign = 0;
second_number = 0;
second_sign = 0;
third_number = 0;
is_legal = 0;
}
void create_formula() {
do {
first_number = rand() % 100 + 1;
first_sign = rand() % 4 + 1;
second_number = rand() % 100 + 1;
second_sign = rand() % 4 + 1;
third_number = rand() % 100 + 1;
is_legal = 0;
if (first_sign == 1) {
if (second_sign == 1) {
if (first_number + second_number + third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 2) {
if (first_number + second_number <= 1000 && first_number + second_number - third_number >= 0) {
is_legal = 1;
}
}
if (second_sign == 3) {
if (first_number + second_number * third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 4) {
if (second_number % third_number == 0 && first_number + second_number / third_number <= 1000) {
is_legal = 1;
}
}
}
if (first_sign == 2) {
if (second_sign == 1) {
if (first_number - second_number >= 0 && first_number - second_number + third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 2) {
if (first_number - second_number - third_number >= 0) {
is_legal = 1;
}
}
if (second_sign == 3) {
if (first_number - second_number * third_number > 0 && second_number * third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 4) {
if (second_number % third_number == 0 && first_number - second_number / third_number > 0) {
is_legal = 1;
}
}
}
if (first_sign == 3) {
if (second_sign == 1) {
if (first_number * second_number + third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 2) {
if (first_number * second_number <= 1000 && first_number * second_number - third_number >= 0) {
is_legal = 1;
}
}
if (second_sign == 3) {
if (first_number * second_number * third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 4) {
if (first_number * second_number <= 1000 && (first_number * second_number) % third_number == 0) {
is_legal = 1;
}
}
}
if (first_sign == 4) {
if (second_sign == 1) {
if (first_number % second_number == 0 && first_number / second_number + third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 2) {
if (first_number % second_number == 0 && first_number / second_number - third_number >= 0) {
is_legal = 1;
}
}
if (second_sign == 3) {
if (first_number % second_number == 0 && first_number / second_number * third_number <= 1000) {
is_legal = 1;
}
}
if (second_sign == 4) {
if (first_number % (second_number * third_number) == 0) {
is_legal = 1;
}
}
}
} while (is_legal == 0);
cout << first_number;
switch (first_sign) {
case 1: cout << "+"; break;
case 2: cout << "-"; break;
case 3: cout << "*"; break;
case 4: cout << "/"; break;
}
cout << second_number;
switch (second_sign) {
case 1: cout << "+"; break;
case 2: cout << "-"; break;
case 3: cout << "*"; break;
case 4: cout << "/"; break;
}
cout << third_number << endl;
}
void calculate() {
int n;
bool is_correct = false;
cout << "input answer:";
cin >> n;
if (first_sign == 1) {
if (second_sign == 1) {
if (first_number + second_number + third_number == n) {
is_correct = true;
}
}
if (second_sign == 2) {
if (first_number + second_number - third_number == n) {
is_correct = true;
}
}
if (second_sign == 3) {
if (first_number + second_number * third_number == n) {
is_correct = true;
}
}
if (second_sign == 4) {
if (first_number + second_number / third_number == n) {
is_correct = true;
}
}
}
if (first_sign == 2) {
if (second_sign == 1) {
if (first_number - second_number >= 0 && first_number - second_number + third_number == n) {
is_correct = true;
}
}
if (second_sign == 2) {
if (first_number - second_number - third_number == n) {
is_correct = true;
}
}
if (second_sign == 3) {
if (first_number - second_number * third_number == n) {
is_correct = true;
}
}
if (second_sign == 4) {
if (first_number - second_number / third_number == n) {
is_correct = true;
}
}
}
if (first_sign == 3) {
if (second_sign == 1) {
if (first_number * second_number + third_number == n) {
is_correct = true;
}
}
if (second_sign == 2) {
if (first_number * second_number - third_number == n) {
is_correct = true;
}
}
if (second_sign == 3) {
if (first_number * second_number * third_number == n) {
is_correct = true;
}
}
if (second_sign == 4) {
if (first_number * second_number / third_number == n) {
is_correct = true;
}
}
}
if (first_sign == 4) {
if (second_sign == 1) {
if (first_number / second_number + third_number == n) {
is_correct = true;
}
}
if (second_sign == 2) {
if (first_number / second_number - third_number == n) {
is_correct = true;
}
}
if (second_sign == 3) {
if (first_number / second_number * third_number == n) {
is_correct = true;
}
}
if (second_sign == 4) {
if (first_number / second_number / third_number == n) {
is_correct = true;
}
}
}
if (is_correct) {
cout << "The answer is correct." << endl;
correct_count++;
} else {
cout << "The answer is wrong." << endl;
incorrect_count++;
}
int total = correct_count + incorrect_count;
if (total > 0) {
double accuracy = (double)correct_count / total * 100;
cout << "Correct: " << correct_count << ", Wrong: " << incorrect_count << endl;
cout << "Accuracy: " << accuracy << "%" << endl;
}
}
bool is_continue() {
char to_continue;
cout << "press Y to continue, or N to finish: ";
cin >> to_continue;
return (to_continue == 'Y' || to_continue == 'y');
}
};
int main() {
srand(time(0));
formula f1;
bool continue_playing = true;
while (continue_playing) {
f1.create_formula();
f1.calculate();
continue_playing = f1.is_continue();
}
return 0;
}
代码的核心思想很简单,就是随机生成3个1-100的整数,和2个1-4的整数。
其中2个1-4的整数分别代表+-×÷4种运算符,随后通过嵌套if…else…进行判断算式类型,并进行合法性检查、运算等操作。
算式的输出采用了switch…case…判断运算符号类型并通过流式输出将完整算式输出。
p.s:正常是不是应该用堆栈来做计算器来着?
在代码运行的过程中,目测发现纯加减法题目占比较大,而几乎没有出现双乘法、双除法或乘除法混合的题目,可能是因为双乘法容易溢出(³√(1000)=10),而双除法容易在结果中出现小数,导致不合法,而被重新生成。目前想不到很合理的房间解决这个问题。
个人体会:
本次实验通过双人协作编程的方式,给我带来最大的提升是可以在不需要打断自己的思路的情况下,将一些需要查询的内容交由伙伴进行处理。同时在编写代码的时候,伙伴可以在边上同步阅读代码,避免在编写时出现一些中文标点、漏分号之类的错误。
队友体会:
处理用户输入时,最初直接用cin>>导致换行符残留,后来学会用getchar()清理缓冲区,意识到输入流的细节处理很关键。
在编写代码的时候不能墨守成规,需要根据实际情况决定数据结构和逻辑结构。

浙公网安备 33010602011771号