二柱子的三个阶段——随机生成四则运算题目(java语言版)
Posted 前端开发学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二柱子的三个阶段——随机生成四则运算题目(java语言版)相关的知识,希望对你有一定的参考价值。
今日下午在课上的最后40分钟遇到了经典的二柱子测试有个阶段组成,难度逐层增加,需求逐步增多,长话短说直接进入正题:
测试一和测试二较为简单,生成随机数并且保证不会有重复的题目,就可以完成
在这我将测试一和测试二合并完成,先简单描述一下我对问题的思路:
首先确定打印问题的数量,自己定义输入即可: Scanner sc=new Scanner (System.in); int num=sc.nextInt();
在这我们可以看到这里是两个操作数参与运算,所以我就简单定义了两个数组,用于存放两个参与随机运算的操作数,int []num1=new int[num+1];
int []num2=new int[num+1];
这里参与循环,循环结束的条件就是生成要求的题目数量
num1[i]=r.nextInt(100);
num2[i]=r.nextInt(100);
有多少道题就有多少个操作数,num+1是为了在接下的循环导致数组下标越界。
进行随机生成运算符的操作,这里只是简单的+-*/,所以我采用了这种方式表示:Random r=new Random();int ch=r.nextInt(3);ch的取值范围是(0,1,2,3),将ch对4取余,余数为0,1,2,3分别对应 + - * /。
判断题目是否重复也是我定义两个数组的原因:在每次生成两个随机数中只要有一个随机数没有出现重复,就可以认为这道题不被重复,当然这种做法也有点不合理
下面为代码展示:
package Secondweek; import java.util.Random; import java.util.Scanner; public class Question { public static void main(String[] args) { System.out.println("请输入出题数目:"); Scanner sc=new Scanner(System.in); int sum=sc.nextInt(); int n=0; int []num1=new int[sum+1]; int []num2=new int[sum+1]; System.out.println("请输入操作数个数:"); int num=sc.nextInt(); for(int i=0;i<=sum;i++) { Random random=new Random(); num1[i]=random.nextInt(100); num2[i]=random.nextInt(100); int ch=random.nextInt(3); switch(ch) { case 0: for(int j=0;j<i;j++) { if((num1[i]!=num1[j])||(num2[i]!=num2[j])) { System.out.println(num1[i]+"+"+num2[i]); break; } } n++; break; case 1: for(int j=0;j<i;j++) { if((num1[i]!=num1[j])||(num2[i]!=num2[j])) { System.out.println(num1[i]+"-"+num2[i]); break; } } n++; break; case 2: for(int j=0;j<i;j++) { if((num1[i]!=num1[j])||(num2[i]!=num2[j])) { System.out.println(num1[i]+"*"+num2[i]); break; } } n++; break; case 3: for(int j=0;j<i;j++) { if((num1[i]!=num1[j])||(num2[i]!=num2[j])) { System.out.println(num1[i]+"*"+num2[i]); break; } } n++; break; } } } }
因为这道题的题目是逐层递进的,要求是逐层增多的,到了第三阶段,额,我先给大家展示一下第三阶段的要求:
就一个定制操作数个数的要求让我对接下来的思考找不到方向,我不能定义任意个数组,有人推荐我使用二维数组,我当场就放弃了,主要还是自己所学的知识有限(数组就是那种没学会的那种),对于刚上大二,对于任何一门编程语言都是半吊子的我,但借鉴班里的大佬这点脸皮我还是有的,接下来为大家展示第三阶段的代码,这里面的加括号的要求我还有些不理解,其它的都已经能够完成,当然这段生成括号的代码我想也没能完成题目的要求
代码如下:
package Secondweek; import java.util.Scanner; import java.util.Random; public class Secondzhu { public static void main(String[] args) { Secondzhu A=new Secondzhu(); System.out.println("请输入你要出题数量:"); Scanner sc=new Scanner(System.in); int num1=sc.nextInt(); System.out.println("请输入题目的操作数个数:"); int num2=sc.nextInt(); System.out.println("请输入操作数的取值范围:"); int range=sc.nextInt(); System.out.println("请选择有无乘除法(1:有,0:无)"); int op1=sc.nextInt(); System.out.println("请选择有无括号(1:有,0:无)"); int op2=sc.nextInt(); if(op1==1||op2==0) { A.questionTool(num1,num2,op1,op2,range); }else { System.out.println("输入错误请重新输入!"); return; } } //定义一个方法生成题目 public void questionTool(int num1,int num2,int op1,int op2,int range) { Random r=new Random(); int []str1=new int[num1*100]; //生成题目的数量 int []str2=new int[num2*2-1]; //每道题有数组中的元素构成,分别由操作数和运算符组成,且他们的关系运算符个数为操作数减一 //int mark=0;//定义一个记号防止生成的题目是否重复 for(int j=0;j<num1/*-mark*/;j++)//循环生成题目 { boolean x=true; //定义两个括号的位置,我也不清楚为什么这样定义 int frontk=r.nextInt(num2-1); int behindK=r.nextInt(num2-frontk)+frontk+1; //生成所有的随机数,符号另作处理 for(int i=0;i<num2*2-1;i++) { str2[i]=r.nextInt(range); } //定义一个流氓算法(计算生成每道题目的随机数总和,若总和相同则就被认为重复),防止出现重复的题目,这个算法是有缺陷的 for(int t=0;t<num2;t++) { str1[j]+=str2[t*2]*t; //*t有种更保险的感觉 } //判断是否重复 for(int n=0;n<j;n++) { if(str1[n]==str1[j]) { num1++; x=false; break; } } //生成题目的过程,在一道题目数组中,操作数的下标永远为偶数(不考虑符号),运算符的下标为奇数,所以在下表偶数是输出随机数,在奇数下标讨论输出运算符 if(x) { for(int i=0;i<num2*2-1;i++) { if(op2==1)//先从判断有无括号选择分支结构 { if(2*frontk==i) System.out.print("("); if(i%2==0&&i!=num2*2-2) //下标为偶数 { System.out.print(str2[i]+" "); if(2*str2[i]-2==i) System.out.println(")"); }else if(i == num2*2-2) //当下表为最后一个偶数时,对括号的增加另作处理。 { System.out.print(str2[i]); if( 2*behindK - 2 == i) System.out.print(")"); System.out.println(" ="); }else if(i%2==1) { if(op1==1) //有无乘除 { if(str2[i]%4==0) { System.out.print("+"); } else if(str2[i]%4==1) { System.out.print("-"); } else if(str2[i]%4==2) { System.out.print("*"); } else if(str2[i]%4==3) { System.out.print("/"); } }else if(op1==0) { if(str2[i]%2==0) { System.out.print("+"); } else if(str2[i]%2==1) { System.out.print("-"); } } } }else { if(i%2 == 0 && i!= num2*2-2) { System.out.print(str2[i] + " "); } else if(i == num2*2-2) { System.out.println(str2[i] + " ="); if( 2*behindK - 1 == i) System.out.print(")"); }else if(i%2==1) { if(op1==1) //有无乘除 { if(str2[i]%4==0) { System.out.print("+"); } else if(str2[i]%4==1) { System.out.print("-"); } else if(str2[i]%4==2) { System.out.print("*"); } else if(str2[i]%4==3) { System.out.print("/"); } }else if(op1==0) { if(str2[i]%2==0) { System.out.print("+"); } else if(str2[i]%2==1) { System.out.print("-"); } } } } } } } } }
这个整体的思路就与我相差很多,但我自己为这段代码添加了注释也方便你们理解,令我脑洞大开的是他将一道题目以数组的形式来完成,这个需要对一道题目的构成分解到为,思路十分清晰,众所周知,变成就是将我们难以下手的问题分解,分解到我们能够解决的程度,他这里将一道题目分解到了数组中的元素程度上,让我对分解这一操作认识更加深刻,如有疑问欢迎评论等方式与我交流。
以上是关于二柱子的三个阶段——随机生成四则运算题目(java语言版)的主要内容,如果未能解决你的问题,请参考以下文章