这周比上周的要求增多:
程序设计思想:
1.根据学生所处的年级不同,设置了不同难度的题目:二年级,三年级,四年级,可以根据小朋友所处的年级选择相应的题目;
2.根据出题的难度,随机数确定运算式包含的参数个数,随机数确定符号,参数个数比运算符号多一个,生成题目;
3.将题目传给栈,由栈计算结果,并返回结果;
4.获取输入的答案,比对正确答案,可以输出错误的题目,并且计算正确率。
1.1二年级题目:
1 class TwoGrade{ 2 //难度为小学二年级 3 4 /** 5 *1.可以实现2-3个参数的两位数的加减法 6 *2.可以实现一位数的乘法 7 *3.可以实现整除,无余数 **/ 8 Random ra=new Random(); 9 10 public question count(){ //随机出题函数 11 String[] c={"+","-"};//加减运算符 12 String[] cc={"*","/"};//乘除运算符 13 14 String s="";//设定返回的字符串 15 String sss="";//将除号变为÷ 16 String answer="";//设定返回的答案 17 18 question q=new question();//设定问题类 19 20 int jjorcc=ra.nextInt(3); 21 switch(jjorcc){ //选择加法或者减法 22 case 0:{ //加减法 23 int num=ra.nextInt(3)+2;//参数的个数; 24 int[] arr=new int[num];//保存参数 25 26 for(int i=0;i=0)break; 83 q=count(); 84 } 85 System.out.print("("+(i+1)+")"+q.get_s()+"="); 86 double answer =sc.nextDouble(); 87 if(q.get_answer()!=answer){v.addElement(i+1);} 88 } 89 else{ 90 System.out.print("("+(i+1)+")"+q.get_s()+"="); 91 double answer =sc.nextDouble(); 92 //if(q.get_yushu().equals(null)){ 93 if(q.get_answer()!=answer){v.addElement(i+1);} 94 //} 95 //else{ 96 //if((q.get_answer()!=answer)){v.addElement(i+1);} 97 //} 98 //若该题错误,保存题号 99 }100 }101 102 //输出结果103 for(int i=0;i
1.2程序截图
1)可以实现100以内的加减的二至三个参数个数随机的运算,减法无负数
2)可以实现10以内的乘除的两个参数运算,除法无余数
1.3设计思路
用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果:若结果正确则不输出,结果错误记录题号 ,输出。
查了小学课本,小学二年级的数学题基本实现,只要根据小朋友的年级就可以出对应的题目。
2.1三年级题目
1 class ThreeGrade{ //难度为小学三年级 2 /** 3 * 1.可以实现2-5个参数的万以内的加减法 4 * 2.可以实现两位数的乘法,除数为一位的除法,结果可有余数 5 **/ 6 static Random ra=new Random(); 7 8 public static question count(){ //出题函数 9 10 String[] c={"+","-"};//加减运算符 11 String[] cc={"*","/"};//乘除运算符 12 13 String s="";//设定返回的字符串 14 String sss="";//将除号改为"÷" 15 String answer="";//设定返回的答案 16 int yuyuyu=0;//记录除法的被除数 17 18 question q=new question();//设定问题类 19 20 int jjorcc=ra.nextInt(3); 21 switch(jjorcc){ //选择加法或者减法 22 case 0:{ //加减法 23 int num=ra.nextInt(5)+2;//参数的个数; 24 int[] arr=new int[num];//保存参数 25 26 for(int i=0;i=0)break; 86 q=count(); 87 } 88 System.out.print("("+(i+1)+")"+q.get_s()+"="); 89 int answer =sc.nextInt(); 90 if(q.get_answer()!=answer){v.addElement(i+1);} 91 } 92 else{ 93 System.out.print("("+(i+1)+")"+q.get_s()+"="); 94 int answer =sc.nextInt(); 95 if(q.get_yushu().equals("")){ //如果没有余数 96 if(q.get_answer()==answer){} 97 else{v.addElement(i+1);} 98 } 99 else{ //如果有余数100 String yu=sc.next();101 if(q.get_answer()==answer&&q.get_yushu().equals(yu)){}102 else{v.addElement(i+1);}103 }104 }105 }106 107 //输出结果108 for(int i=0;i
2.2程序截图
1)可以实现10000以内的加减的二至五个参数个数随机的运算,减法无负数
2)可以实现100以内的乘除的两个参数运算,除法有余数,要写出来
2.3设计思路
用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果,若有余数则输入余数(以字符串形式保存):若结果正确则不输出,结果错误记录题号 ,输出。
查了小学课本,小学三年级的数学题基本实现,只要根据小朋友的年级就可以出对应的题目。
3.1四年级题目
1 ass FenShu { 2 private int denominator,numerator; 3 4 public int getDenominator() { 5 return denominator; 6 } 7 8 public void setDenominator(int denominator) { 9 this.denominator = denominator;10 }11 12 public int getNumerator() {13 return numerator;14 }15 16 public void setNumerator(int numerator) {17 this.numerator = numerator;18 }19 20 public FenShu(int denominator, int numerator) {21 this.denominator = denominator;22 this.numerator = numerator;23 yueJian();24 }25 26 FenShu(){}27 28 //约简29 public void yueJian(){30 int y = 1;31 for(int i = numerator;i > 1;i--){32 if(numerator % i == 0 && denominator % i == 0){33 y = i;34 break;35 }36 }37 numerator /= y;38 denominator /= y;39 40 }41 42 //加43 public FenShu add(FenShu b){44 FenShu c = null;45 int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator();46 int nDenominator = this.denominator * b.getDenominator();47 c = new FenShu(nDenominator,nNumerator);48 return c;49 }50 51 //减52 public FenShu subtract(FenShu b){53 FenShu c = null;54 int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator();55 int nDenominator = this.denominator * b.getDenominator();56 c = new FenShu(nDenominator,nNumerator);57 return c;58 }59 60 //乘61 public FenShu multiply(FenShu b){62 FenShu c = null;63 int nNumerator = this.numerator * b.getNumerator();64 int nDenominator = this.denominator * b.getDenominator();65 c = new FenShu(nDenominator,nNumerator);66 return c;67 }68 69 //除70 public FenShu divide(FenShu b){71 FenShu c = null;72 int nNumerator = this.numerator * b.getDenominator();73 int nDenominator = this.denominator * b.getNumerator();74 c = new FenShu(nDenominator,nNumerator);75 return c;76 }77 78 //输出分数形式79 public String toString(){80 if(numerator != 0){81 // if(numerator % denominator == 0)82 // return "" + numerator / denominator;83 return numerator + "/" + denominator;84 }85 return "0";86 }87 88 }
1 class FourGrade 2 { 3 static Random ra=new Random(); 4 5 public void print(){ 6 // TODO Auto-generated method stub 7 Scanner scan = new Scanner(System.in); 8 System.out.println("是否有括号(1有,0没有)"); 9 int hasKuoHao = scan.nextInt(); 10 System.out.println("加减有无负数(1有,0没有)"); 11 int hasFuShu = scan.nextInt(); 12 System.out.println("除法有无余数(1有,0没有)"); 13 int hasYuShu = scan.nextInt(); 14 System.out.println("数值范围(最大数)"); 15 int maxNum = scan.nextInt(); 16 17 int n = ra.nextInt(10)+2; 18 String[] yunSuanShiArray = createYunSuanShi(hasKuoHao, hasFuShu, hasYuShu, maxNum, n); 19 for(int i = 0;i < yunSuanShiArray.length;i++){ 20 System.out.println(yunSuanShiArray[i]); 21 } 22 scan.close(); 23 } 24 25 26 //生成整数计算式添加限制条件,type为运算式类型 0代表整数式,1代表真分数式 27 public static String[] createYunSuanShi(int hasKuoHao,int hasFuShu,int hasYuShu,int maxNum,int n) { 28 int i = 0; 29 int hasChengChu=1; 30 String yunSuanShiTemp; 31 String[] yunSuanShiArray = new String[n]; 32 int operatorScope = 2 + 2 * hasChengChu;//运算符范围,2或4,2代表只有加减,4代表有加减乘除 33 int length; 34 String[] operatorArray = {"+","-","*","/"}; 35 String[] operatorNum = null;//存储运算数 36 int num_index;//运算数下标 37 String[] operatorSymbol = null;//存储运算符 38 int symbol_index;//运算符下标 39 int[] brackets = null;//存储括号个数 40 41 while(i < n) { 42 length = Integer.parseInt(getOperatorNumber(0, 9)) + 2;//计算式运算数长度 43 operatorNum = new String[length]; 44 operatorSymbol = new String[length - 1]; 45 num_index = 0; 46 symbol_index = 0; 47 int type=ra.nextInt(2); 48 operatorNum[num_index++] = getOperatorNumber(type, maxNum);//随机生成操作数 49 for(int j = 0;j < length - 1;j++){ 50 operatorSymbol[symbol_index++] = operatorArray[Integer.parseInt(getOperatorNumber(0, operatorScope))];//随机生成操作符 51 operatorNum[num_index++] = getOperatorNumber(type, maxNum);//随机生成操作数 52 } 53 if(hasKuoHao == 1){ 54 brackets = randomAddBracket(length);//生成括号数组 55 } 56 //构造运算式 57 yunSuanShiTemp = ""; 58 for(int j = 0;j < length;j++){ 59 //添加左括号 60 if(hasKuoHao == 1){ 61 for(int k = 0;k < brackets[j];k++){ 62 yunSuanShiTemp += "("; 63 } 64 } 65 yunSuanShiTemp += " " + operatorNum[j] + " ";//加上运算数 66 67 //添加右括号 68 if(hasKuoHao == 1){ 69 for(int k = 0;k > brackets[j];k--){ 70 yunSuanShiTemp += ")"; 71 } 72 } 73 //如果不是最后一个运算数则要加上运算符 74 if(j != length - 1){ 75 yunSuanShiTemp += operatorSymbol[j]; 76 } 77 } 78 79 //计算结果 80 String answer = expressCalculate(yunSuanShiTemp, hasFuShu, hasYuShu, type, length - 1); 81 if((answer.equals("ERROR"))){ 82 continue; 83 } 84 yunSuanShiTemp += "=" + answer; 85 //检验重复 86 boolean chongFu = false; 87 for(int j = 0;j < i;j++){ 88 if((yunSuanShiArray[j].equals(yunSuanShiTemp))){ 89 chongFu = true; 90 break; 91 } 92 } 93 if(chongFu == false){ 94 yunSuanShiArray[i++] = yunSuanShiTemp; 95 } 96 } 97 return yunSuanShiArray; 98 } 99 100 //表达式计算,参数为字符串类型的运算式101 public static String expressCalculate(String express,int hasFuShu,int hasYuShu,int type,int symbolNum){102 Stacknum = new Stack ();103 Stack symbolS = new Stack ();104 symbolS.push("#");105 express += "#";106 char ch;107 int i = 0;108 int s = 0;109 ch = express.charAt(i);110 while(s < symbolNum){111 if(ch == ' '){ //读到空格,说明开始读运算数112 String readNumStr = "";113 while(true){114 ch = express.charAt(++i);115 if(ch == ' '){116 break;117 }118 readNumStr += ch;119 120 }121 if((i + 1) < express.length()){122 ch = express.charAt(++i);123 }124 num.push(readNumStr);125 }else{ //读到的是运算符126 char compare = priorityCompare(symbolS.peek(),ch + "");127 128 if(compare == '='){ //如果是右括号129 symbolS.pop();130 ch = express.charAt(++i);131 }else if(compare == '>'){ //ch的优先级小于栈顶的优先级 比栈顶的优先级高就不算,入栈,低就弹栈运算132 //弹出两个运算数,弹出一个运算符133 String bStr = num.pop();134 String aStr = num.pop();135 String symbolT = symbolS.pop();136 String c = yunSuan(aStr,bStr,symbolT,hasFuShu,hasYuShu,type);137 if(c.equals("ERROR")){138 return "ERROR";139 }else if(c.indexOf("余") >= 0 && s != symbolNum - 1){ //有余数140 return "ERROR";141 }else{142 num.push(c);143 }144 s++;145 }else{146 symbolS.push(ch + "");147 if((i + 1) < express.length()){148 ch = express.charAt(++i);149 }150 }151 152 }153 }154 return num.pop();155 }156 157 public static String yunSuan(String aStr,String bStr,String symbol,int hasFuShu,int hasYuShu,int type){158 if(type == 0){ //整数159 int a = Integer.parseInt(aStr);160 int b = Integer.parseInt(bStr);161 if(symbol.equals("+")){162 return "" + (a + b);163 }else if(symbol.equals("-")){164 if(a - b < 0 && hasFuShu == 0){165 return "ERROR";166 }else{167 return "" + (a - b);168 }169 }else if(symbol.equals("*")){170 return "" + (a * b);171 }else{172 if(b == 0){173 return "ERROR";174 }175 if(a % b == 0){176 return "" + (a / b);177 }else{178 if(hasYuShu == 1){179 return (a / b) + "余" + (a % b);180 }else{181 return "ERROR";182 }183 }184 }185 }else{ //分数186 String[] af = aStr.split("/");187 String[] bf = bStr.split("/");188 if(af[0].equals("0") || bf[0].equals("0")){189 return "ERROR";190 }191 FenShu a = new FenShu(Integer.parseInt(af[1]),Integer.parseInt(af[0]));192 FenShu b = new FenShu(Integer.parseInt(bf[1]),Integer.parseInt(bf[0]));193 if(symbol.equals("+")){194 return a.add(b).toString();195 }else if(symbol.equals("-")){196 FenShu c = a.subtract(b);197 if(hasFuShu == 1 && c.getNumerator() < 0){198 return "ERROR";199 }200 return c.toString();201 }else if(symbol.equals("*")){202 return a.multiply(b).toString();203 }else{204 return a.divide(b).toString();205 }206 }207 } 208 //判断优先级209 public static char priorityCompare(String a,String b){210 char[][] priority = {211 {'>','>','<','<','<','>','>'},212 {'>','>','<','<','<','>','>'},213 {'>','>','>','>','<','>','>'},214 {'>','>','>','>','<','>','>'},215 {'<','<','<','<','<','=','>'},216 {'>','>','>','>',' ','>','>'},217 {'<','<','<','<','<',' ','='}218 };219 int a_index = index_symbol(a);220 int b_index = index_symbol(b);221 return priority[a_index][b_index];222 }223 224 public static int index_symbol(String a){225 String p = "+-*/()#";226 return p.indexOf(a);227 }228 229 //随机生成括号,参数为运算式的运算数的个数230 public static int[] randomAddBracket(int length){231 int[] brackets = new int[length];232 for(int i = 0;i < brackets.length;i++) brackets[i] = 0;233 Random rd = new Random();234 for(int i = 2;i < length;i++){ //添加的括号长度(括号包围的运算数的个数)235 for(int j = 0;j < length - i + 1;j++){236 int t = rd.nextInt(2);//随机生成0或1,0代表不加括号,1代表加括号237 if(t == 1){238 if(brackets[j] >= 0 && brackets[j + i - 1] <= 0){ //要加的括号的第一个运算数周围没有右括号,且 最后一个运算数周围没有左括号239 int counteract = 0;240 for(int k = j;k < j + i;k++){ //将要加的括号之间的所有运算数对应的brackets相加,241 //如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象242 counteract += brackets[k];243 }244 if(counteract == 0){245 brackets[j]++;246 brackets[j + i - 1]--;247 }248 }249 }250 }251 }252 return brackets;253 }254 255 //随机生成一个运算数( type==0代表生成整数,type==1代表生成真分数,maxNum代表数值范围 0-(maxNum-1) )256 public static String getOperatorNumber(int type,int maxNum){257 Random rd = new Random();258 int a;259 while(true){260 a = rd.nextInt(maxNum);261 if(type == 0){ //随机生成一个整数262 return "" + a;263 }else{ //随机生成一个真分数264 if(a == 0){265 continue;266 }267 int b = rd.nextInt(a);268 FenShu c = new FenShu(a,b);269 return c.toString();270 }271 }272 }273 274 }
3.2程序截图
1)可以实现10000以内的加减的二至十个参数个数随机的运算,减法有负数
2)可以实现100以内的乘除的两个参数运算,除法可以有余数,可以用小数表示
3)可以实现整数的四则运算,可以实现分数的四则运算
4)可以实现小括号的运算
5)可以人为设定题目的类型
3.3设计思路
用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果,若有余数则输入余数(以字符串形式保存):若结果正确则不输出,结果错误记录题号 ,输出。
1)分数实现,设计分数类,包括:分数的构造,先确定分母,如果分母为0,则再生成一个数直到不为0,在0到分母的范围内随机生成分子;
分数的加减乘除运算,先实现同分,再进行相应的运算,分数的输出分子分母之间加“/”。
2)括号实现,设运算式长度为n,则可建立一个长度为n的数组名为kuohao,记录每个元素周围的括号情况,0为无括号,正数为左括号,负数为右括号。则可以产生的括号的长度(即括号包围的运算数的个数)为2 ~ (n-1),利用for循环控制括号的长度,循环变量 i 为2 ~ (n - 1),循环体是另一个循环,循环变量 j 为0 ~ (n - i + 1) (即可以加左括号的运算数的位置),内层循环循环体为:随机生成0或1,1代表加括号,但是还要判断在这是否可以加括号,如果a[j] >=0 (即这个运算数这没有右括号) 且 a[j + i - 1] <= 0(即产生的这个括号的右括号的那个运算数周围没有左括号) 且 sum(a[j] ...... a[j + i - 1]) == 0 (即要加的这个括号之间的括号必须全部匹配,不能因为加上这个括号产生括号交叉现象)变量 j 为0 ~ (n - i + 1)。
编程总结:
1)可以实现根据年级的选择智能出题,少了一些选择,更加方便。
2)括号问题有一部分参考别人的代码,还未能自己实现,需要多加练习。
3)将近花了两个星期的时间,改了删删了改,总有一些自己不满意的地方,下次一定要在写程序之前,勾画好思路,编程也不要莽莽撞撞。