大一大作业出题中有一个小学生随机出题系统,刚好学习了随机函数,就选择这个,结果上手后才发现不是这么简单,最终耗时挺久终于完成了最难的出题模块,分享给大家
#include <bits/stdc++.h>
using namespace std;
void numcraet(double t);
void title(char s1,char s2,int t1,int t2,int t3,int t4);
char pcreat();
void numscreat(double t);
int p=0;
int m;
int main()
{
int z,M,N;
char a;
srand(time(0));
printf("请输入页数\n");
cin>>M;
printf("请输入每页题目数\n");
cin>>N;
int t;
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
z=1+rand()%2;//z==1or2
t=rand()%2;//t==0or1
if(t==1)//t 用来随机决定生成哪种类型
title('(',a,z,z,0,0);//
else if(t==0)//
title(a,a,z,z,1,0);//
cout<<'='<<' '<<' '<<' '<<' ';//
}
cout<<endl;
}
return 0;
}
void titlecreat()
{
char a;
int z,t;
z=1+rand()%3;//决定生成几个括号
t=rand()%2;//决定首先是否生成括号
if(t==1) title('(',a,z,z,0,0);
else if(t==0) title(a,a,z,z,1,0);//z是括号个数
cout<<'=';
}
int numcreat()//生成数字
{
return 1+rand()%100;
}
char pcreat()//生成运算符
{
int t;
t=rand()%4;
if(t==0) return '+';
if(t==1) return '-';
if(t==2) return '*';
if(t==3) return '/';
}
void numscreat()//生成单个运算
{
int num;
char s;
num=numcreat();
cout<<num;
s=pcreat();
cout<<s;
num=numcreat();
cout<<num;
}
void title(char s1,char s2,int t1,int t2,int t3,int t4) //t3,t4是现存左右括号
{
int m;
m=0;
int num;
char s;
int ta=rand()%2;//[0,1]
int tb=rand()%2;//随机
int tc=rand()%2;
int td=rand()%2;
char a;
if(s1=='('&&t1>0)//如果s1==(,输出(,t1--。进入下一个函数
{
p++;
cout<<'(';
t1--;
title(a,a,t1,t2,1,0);
}
else if(s1==a)//s1不为(有两种情况.
{
if(t3==1)//t3==1
{
numscreat();//生成一对运算
if(tb==1&&p>0)//决定 是否生成右括号
{
p--;
title(a,')',t1,t2,0,0);
}
else title(a,a,t1,t2,0,1);
}
else if(t4==1)//t4==1
{
s=pcreat();
cout<<s;
if(s=='/') m=1;
if(tc==0&&t1>0&&m==0) title('(',a,t1,t2,0,0);//决定是否生成左括号
else title(a,a,t1,t2,1,0);
}
}
if(s2==')')
{
t2--;
cout<<')';
if(t2==0)
{
s=pcreat();
cout<<s;
num=numcreat();
cout<<num;
return;
}
else
{
s=pcreat();
cout<<s;
if(s=='/') m=1;
if(td==0&&t1>0&&m==0) title('(',a,t1,t2,0,0);//决定是否生成左括号
else title(a,a,t1,t2,1,0);
}
}
}
输出结果如下:
如上图,逻辑有点复杂,下面是解析:
首先要知道,一个混合四则运算包括什么:数字,运算符,括号。按照顺序将他们拼接在一起就能得到一个运算。
再进一步,我们将数字和运算符组合成单个运算,即代码中的numscreate模块(代码中的单词拼错了)(狗头),numscreate模块由pcreate和numcreate组成。
再进一步,如果我们将单个运算组合起来,其中穿插括号,就能得到一个四则混合运算了。
可是困难的是如何将他们组合起来,并让其中穿插括号。一番思考之后,自然地想到了递归,简直和递归完美契合(哈哈)。
我们设置一个值,假如是p1,我们给他赋一个随机值,代表递归层数,每次递归减一,到零为止。可以表示运算的长短。
假设一个t1,判断是否生成括号,设置一个t2,判断生成括号是否合法(可以参考力扣20题,有效的括号)。
这样就可以将括号和单个运算组合起来了。
最后是细节处理,一个是除法不能除零,有时候括号也不允许(括号内可能为零),可以加入一个判断,如果随机生成了除法就不能在后面生成括号,零懒得搞了,就规定随机数不生成零(聪明)。还有一个是可能生成类似与 (3+5)= 这样的运算,为了美观决定再最后加一个运算符和数字(所以最后生成的都是奇数个数字)
优化点:无法实现去重
代码就是按照这个思路写的,如果想深入了解,可读一下代码
大一萌新,如有错误,敬请指正,如果觉得对你有帮助,请点一个赞哦(⊙o⊙)?