随机生成四则运算式2
接着上次的程序,老师又给二柱子增加了几个条件,对程序再做进一步的改进,要求满足如下条件:
1.题目避免重复。
2.可制定。(数量/打印方式)
3.可以控制下列参数:
- 是否有乘除法
- 是否有括号(最多可支持10个数参与计算)
- 数值范围
- 加减有无负数
- 乘除有无余数
如下是对本题的分析:
针对问题,首先要进行拆分。从最小的功能开始,然后依次实现。首先还是生成一道两个数的四则运算式,这个不难实现。困难的是如何生成多个数的运算式?其实,多个数的运算只是在两个数的基础上进行增加的,所以可以把上一次生成的运算式当作一个数,再与随机生成的另一个数合成一个运算式,如此循环,直到整个运算式的数字个数满足我想要达到的数量为止。那么问题又来了,数字是整型,符号为字符型,究竟如何合在一块进行输出呢?经过分析发现,字符串有的合成可以直接把几个字符串相加,于是可以把每一次生成的运算式转换成字符串的形式来存放,这个过程中要使用到itoa()函数。这样的话如果要加入“()”也会变得非常简单,如:equation=‘(’+equation+‘)’+new_num。
而如此一来,对于后面的查重工作,只需把每次新生成的运算式存放在字符串数组中,依次比较之前生成的运算式中是否有相同项,若有,则此次生成无效,再重新生成一个新的运算式,若没有重复项,则进行下一道运算式的生成工作。直到达到生成运算式的数量为止。
而对其他的要求则可以通过设置用户选择来实现,简单略。
如下是本次问题实现的源代码:
// 按要求随机生成四则运算 王世强 2015/3/10 #include<fstream> #include<iostream> #include<stdlib.h> #include<iomanip> #include<time.h> #include<cmath> #include<string> #include<stdio.h> using namespace std; #define random() (rand()%100000) //符号生成 char create_symbol(int n) { int n1,j; char symbol[1]; if(n==0) { n1=2; } else if(n=1) { n1=4; } j=random()%n1; if(j==0) symbol[0]='+'; else if(j==1) symbol[0]='-'; else if(j==2) symbol[0]='*'; else symbol[0]='/'; return symbol[0]; } //把数字转换成字符串型 string int_string(int number) { int temp=abs(number); char str[200]; itoa(temp,str,10); string str_=str; return str_; } //运算式转换成一个字符串 string combination(string str1,string str2,char k) { string equation; equation=str1+k+str2; return equation; } //主函数 int main() { srand((int)time(NULL)); //设置时间种子 ,使得程序每次运行的结果都不同 int num1,num2,count,n,change,amount,shuchu,range,j,repeat=0,bracket; string str_num1,str_num2,temp; cout<<"有无乘除法?1有,0没有:"<<endl; cin>>n; cout<<"是否有括号?1有,0没有:"<<endl; cin>>bracket; cout<<"题目是否在文件中输出?1是,0不是:"<<endl; cin>>shuchu; cout<<"请输入数字范围:"<<endl; cin>>range; cout<<"请输入出题数量:"<<endl; cin>>amount; string Equation[amount]; char symbol; ofstream fout; if(shuchu==1) { fout.open("fl.txt"); fout<<amount<<"道四则运算题如下:"<<endl; } else { cout<<amount<<"道四则运算题如下:"<<endl; } for(int i=0;i<amount;i++) { num1=random()%range+1; num2=random()%range+1; count=random()%9+2; symbol=create_symbol(n); str_num1=int_string(num1); str_num2=int_string(num2); Equation[i]=combination(str_num1,str_num2,symbol); if(count>2) { for(count;count>2;count--) { symbol=create_symbol(n); str_num1=Equation[i]; if(bracket==1) { change=random()%2; if(change==0) { str_num1='('+str_num1+')'; } } symbol=create_symbol(n); num2=random()%range+1; str_num2=int_string(num2); change=random()%2; if(change==0) { temp=str_num1; str_num1=str_num2; str_num2=temp; } Equation[i]=combination(str_num1,str_num2,symbol); } } //判断是否重复 for(j=0;j<i;j++) { if(Equation[j]==Equation[i]) { i=i-1; repeat=1; break; } } if(repeat!=1)//若不重复,则输出 { if(shuchu==1) { fout<<Equation[i]<<"="<<endl; } else { cout<<Equation[i]<<"="<<endl; } } } if(shuchu==1) { fout.close(); } }
如下是不同条件下运行结果的截图:
接下来是文件输出
查看文件内容:
总结:这次的练习,让我体会到了通过思考解决程序问题的乐趣,回想以前的时候,就是因为怕动手动脑,怕麻烦,总是逃避编程,当醒悟过来时,已经大三了,但是在接下来的时间里,要改掉以前的毛病,珍惜每次练习的机会来提升自己的能力!
项目计划总结:
日期&&任务 | 听课 | 编写程序 | 阅读相关书籍 | 网上查找资料 | 日总计 |
周一 | 2 | 4 | 2 | 2 | 10 |
周二 | 3 | 1 | 4 | ||
周三 | |||||
周四 | 2 | 2 | 4 | ||
周五 | 5 | 1 | 1 | 7 | |
周六 | 2 | 2 | |||
周日 | 2 | 2 | |||
周总计 | 4 | 14 | 7 | 4 | 29 |
时间记录日志:
日期 | 开始时间 | 结束时间 | 中断时间 | 净时间 | 活动 | 备注 |
3/7 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程上课 |
16:00 | 18:20 | 140 | 编写程序 | 编写老师布置的作业 | ||
19:00 | 21:00 | 10 | 110 | 阅读书籍 | 《构建之法》 | |
21:00 | 24:00 | 20 | 160 | 网上查找资料,编程 | 作业2,讨论问题 | |
3/8 | 16:00 | 18:00 | 10 | 110 | 查资料,编写程序 | 作业2 |
21:00 | 21:50 | 50 | 阅读书籍 | 《构建之法》 | ||
3/9 | ||||||
3/10 | 14:00 | 15:50 | 10 | 100 | 听课 | 软件工程上课 |
19:00 | 21:20 | 20 | 100 | 查资料,编写程序 | 休息,聊天,作业2 | |
3/11 | 8:00 | 10:05 | 5 | 120 | 写博客 | 发表本周博客 |
16:10 | 18:30 | 10 | 140 | 修改程序,写博客 | 测试程序,发表博客 | |
19:00 | 19:40 | 40 | 阅读书籍 | 《构建之法》 | ||
19:45 | 21:45 | 10 | 110 | 写博客,修改程序 | 休息,聊天,发表博客 | |
3/12 | 9:00 | 9:30 | 30 | 阅读书籍 | 计划阅读《构建之法》 | |
3/13 | 19:00 | 19:30 | 30 | 阅读书籍 | 计划阅读《梦断代码》 |
缺陷记录日志:
在完成的过程中,改用了新的方法,大部分代码都有改写,出现过个别语法错误,都是由于马虎造成的,具体的过程就没有统计,下周学习过程中会慢慢养成记录的习惯!