小学生终结者——四则运算生成器
==================前言==================
这是一个交互十分差的东西,使用cmd运行jar包运行,由于公司经费问题,暂时没能发布exe版本。小学生朋友请在专业人员的指导下使用。
==================正文==================
a.需求分析。
当代小学生的计算能力堪忧,为了维护世界的和平安宁,我觉得我必须做些什么。
b.功能设计。
b.1生成小学水平的四则运算题目。
b.2提供回答的功能。
b.3提供批改的功能。
c.设计实现。
生成数字相关类
1 package Method; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Random; 6 import Method.Operate; 7 8 public class Create { 9 public String Createnum(int span,int difcoe){//生成一个数 10 //Random rand = new Random(); 11 int ran = (int)( Math.random() * 10) + 1; 12 int num = 1,num2 = 1;//默认值 13 String s = new String(); 14 //System.out.println("Createnum的ran"+ran); 15 if(ran < difcoe){//难度系数下整数概率生成整数 16 num = (int)( Math.random() * (span + 1));//生成0-span范围的整数 17 s = String.valueOf(num); 18 } 19 else{ //生成分数 20 num = (int)( Math.random() * (span + 1)); 21 num2= (int)( Math.random() * (span + 1)) + 1;//坟墓避免出现0 22 s = "("+String.valueOf(num) + "/" +String.valueOf(num2)+")";//生成坟墓分子都在0-span范围的分数,其实其值也在这个范围 23 } 24 25 return s; 26 } 27 public String CreateArith(){ //生成算术符 28 String s = new String(); 29 int ran = (int)( Math.random() * 4) + 1; 30 //System.out.println("Atith的ran"+ran); 31 switch(ran){ 32 case 1: 33 s = "+"; 34 break; 35 case 2: 36 s = "-";; 37 break; 38 case 3: 39 s = "*";; 40 break; 41 case 4: 42 s = "/";; 43 break; 44 } 45 return s; 46 } 47 public String CreateBracket(String ins){//加括号的神奇特效 48 return "("+ins+")"; 49 } 50 //生成一个算术横式 51 public String CreateQues(int span,int difcoe){ 52 String s = new String(); 53 s = s + Createnum(span,difcoe); 54 int coe = (int)( Math.random() * difcoe)+1;//根据难度系数设置一下最长数字数 55 for(int i = 0;i < coe;i++){ 56 int prior = (int)( Math.random() * 10)+1; 57 if(prior>5){//添加新的数字和符号的方向不确定,这样的话括号出现在前还是后就不知道了 58 s = s +CreateArith()+ Createnum(span,difcoe); 59 } 60 else{ 61 s = Createnum(span,difcoe)+ CreateArith() + s; 62 } 63 int r = (int)( Math.random() * 10); 64 if(i<3){ 65 CreateBracket(s); //小概率加个括号,只能前面加 66 } 67 } 68 return s; 69 } 70 //生成题目集 71 public List CreateQList(int totle,int span,int difcoe){ 72 //List temp; 73 List<String> temp = new ArrayList<String>(); 74 String s = "1+1"; 75 Operate a = new Operate(); 76 for(int i = 0;i<totle;i++){ 77 s = CreateQues(span,difcoe); 78 temp.add(s); 79 //System.out.println("*******等于*******"+a.calcbra(s)); 80 } 81 return temp; 82 } 83 }
输入输出
1 package Method; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.FileReader; 8 import java.io.IOException; 9 import java.nio.CharBuffer; 10 import java.util.ArrayList; 11 import java.util.List; 12 13 public class InOut { 14 15 public boolean oute(String textname,List l,String oute){//输出题目 16 byte[] buff=new byte[]{}; 17 int len = l.size(); 18 19 try 20 { 21 for(int i = 0;i < len;i++){ 22 String aa= (String)l.get(i); 23 buff=aa.getBytes(); 24 if(i==0){ 25 FileOutputStream out=new FileOutputStream("D://"+oute,false); //第一次覆盖 26 out.write(buff,0,buff.length); 27 out.write("\r\n".getBytes()); 28 } 29 else{ 30 FileOutputStream out=new FileOutputStream("D://"+oute,true); 31 out.write(buff,0,buff.length); 32 out.write("\r\n".getBytes()); 33 } 34 //FileOutputStream out=new FileOutputStream("D://"+textname,true); 35 36 } 37 38 } 39 catch (FileNotFoundException e) 40 { 41 e.printStackTrace(); 42 } 43 catch (IOException e) 44 { 45 e.printStackTrace(); 46 } 47 return true; 48 } 49 public boolean outg(String ina,String ine,String outg){//输出成绩 50 List<String> ans = new ArrayList<String>(); 51 List<String> que = new ArrayList<String>(); 52 List<String> gra = new ArrayList<String>(); 53 File afile=new File("D:\\"+ina); //回答路径 54 File qfile=new File("D:\\"+ine);//题目路径 55 if(!qfile.isDirectory()||!afile.isDirectory()){ 56 System.out.println("文件不存在!"); 57 }else{ 58 System.out.println("稍等"); 59 } 60 BufferedReader reader=null; 61 String s=null; 62 int line=1; 63 try{ 64 reader=new BufferedReader(new FileReader(afile)); 65 while((s=reader.readLine())!=null){ 66 ans.add(s); 67 line++; 68 } 69 reader=new BufferedReader(new FileReader(qfile)); 70 while((s=reader.readLine())!=null){ 71 que.add(s); 72 System.out.println("输入题目:"+line+":"+s); 73 line++; 74 } 75 } 76 catch(Exception e){ 77 e.printStackTrace(); 78 } 79 finally{ 80 if(reader!=null){ 81 try{ 82 reader.close(); 83 } 84 catch(Exception e){ 85 e.printStackTrace(); 86 } 87 } 88 } 89 //判断是否正确 90 Operate a = new Operate(); 91 String trueno ="正确的题号:"; 92 String falseno ="错误的题号:"; 93 int truenum = 0; 94 int alen = ans.size(); 95 int qlen = que.size(); 96 if(alen!=qlen){ 97 System.out.println("多做还是少做了!!??"); 98 return false; 99 } 100 for(int i = 0;i<alen;i++){ 101 String str =null; 102 String str2 =null; 103 str = ans.get(i); 104 str2 = que.get(i); 105 if(Integer.parseInt(a.calcbra(str2))!=Integer.parseInt(str)){ 106 System.out.println("正确答案:"+ a.calcbra(str2)); 107 System.out.println("你的答案:"+ a.calcbra(str)); 108 str="0"; 109 gra.add(str); 110 falseno = falseno + String.valueOf(i+1) + " "; 111 } 112 else{ 113 str="1"; 114 gra.add(str); 115 truenum++; 116 trueno = trueno + String.valueOf(i+1) + " "; 117 } 118 } 119 //输出结果 120 List<String> l = new ArrayList<String>(); 121 l.add("正确总数:"+String.valueOf(truenum)); 122 l.add(trueno); 123 l.add("错误总数:"+String.valueOf(alen-truenum)); 124 l.add(falseno); 125 if(truenum>5){ 126 l.add("恭喜您获得'得集美实验小学三年级扛把子'称号!"); 127 } 128 byte[] buff=new byte[]{}; 129 int len = l.size(); 130 try 131 { 132 for(int i = 0;i < len;i++){ 133 String aa= (String)l.get(i); 134 String path = "D://"+outg; 135 buff=aa.getBytes(); 136 if(i==0){ 137 FileOutputStream out=new FileOutputStream(path,false); //第一次覆盖 138 out.write(buff,0,buff.length); 139 out.write("\r\n".getBytes()); 140 } 141 else{ 142 FileOutputStream out=new FileOutputStream(path,true); 143 out.write(buff,0,buff.length); 144 out.write("\r\n".getBytes()); 145 } 146 //FileOutputStream out=new FileOutputStream("D://"+textname,true); 147 148 } 149 150 } 151 catch (FileNotFoundException e) 152 { 153 e.printStackTrace(); 154 } 155 catch (IOException e) 156 { 157 e.printStackTrace(); 158 } 159 return true; 160 } 161 }
计算
1 package Method; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.regex.Pattern; 6 7 public class Operate { 8 /** 9 *该方法完成不带括号表达式的计算,返回运算结果 10 */ 11 public String calc(String oper){ 12 List<Character> op = Oper_op2(oper); 13 List<Double> cha = Oper_cha2(oper); 14 15 //遍历运算符容器,完成乘除运算 16 for(int i=0;i<op.size();i++){ 17 Character c = op.get(i); 18 if(c=='*'||c=='/'){ 19 op.remove(i);//是乘除符号则将其从集合中移除出来 20 //取得运算数字,从数字容器中获得对应索引的字符 21 Double opl = cha.remove(i);//拿到运算符左侧数字 22 Double opr = cha.remove(i);//拿到运算符右侧数字 23 //将运算结果放回,将运算后的数放在数字容器索引出 24 if(c=='*'){ 25 cha.add(i, opl*opr);//将运算后的数字添加在i的位置,当前i位置的数向后瞬移 26 }else 27 cha.add(i,opl/opr); 28 i--;//运算符容器的指针回到原来的位置,防止跳过下一个运算符 29 } 30 } 31 while(!op.isEmpty()){ 32 //获取运算符 33 Character o = op.remove(0); 34 Double chal = cha.remove(0); 35 Double chara = cha.remove(0); 36 if(o=='-'){ 37 chal = chal-chara; 38 } 39 if(o=='+'){ 40 chal = chal+chara; 41 } 42 cha.add(0,chal); 43 } 44 int res = cha.get(0).intValue(); 45 //return cha.get(0).toString(); 46 return String.valueOf(res); 47 } 48 /** 49 * 得到表达式中所有的运算符 50 */ 51 private List<Character> Oper_op2(String oper) {//将表达式中的符号替换为@符号 52 oper = ChangeMin(oper); 53 String regex = "@[0-9]|[0-9]";//将字符串按照正则表达式分组 54 Pattern pt = Pattern.compile(regex); 55 String[] split = pt.split(oper);//将数组元素放在集合中 56 List<Character> list = new ArrayList<>(); 57 for(int i=0;i<split.length;i++){ 58 String temp = split[i].trim(); 59 if(temp.equals("+")||temp.equals("-")||temp.equals("*")||temp.equals("/")){ 60 list.add(temp.trim().charAt(0)); 61 } 62 } 63 return list; 64 } 65 /** 66 * 从表达式中获得所有参与运算的数字 67 */ 68 private List<Double> Oper_cha2(String oper) { 69 oper = ChangeMin(oper);//将字符串按照运算符切割,得到字符串数组 70 Pattern pt = Pattern.compile("\\+|\\-|\\*|\\/"); 71 String[] split = pt.split(oper);//遍历数组,判断将特殊符号转换成负数符号,并转换成double类型 72 List<Double> list = new ArrayList<>(); 73 for(int i=0;i<split.length;i++){ 74 String single = split[i]; 75 if(single.charAt(0)=='@'){ 76 single = "-"+single.substring(1); 77 } 78 list.add(Double.parseDouble(single)); 79 } 80 return list; 81 } 82 /** 83 * 将表达式的负号‘-’用@符号代替 84 */ 85 private String ChangeMin(String oper) {//将表达式中的负数符号使用特殊符号替代,获得没有负数字符串 86 for(int i=0;i<oper.length();i++){ 87 char c = oper.charAt(i); 88 if(c=='-'){//判断第一个字符是否是负数 89 if(i==0){ 90 oper = "@"+oper.substring(1); 91 }else{ 92 //判断前一个字符是否是+-*/中的一个 93 char cprev = oper.charAt(i-1); 94 if(cprev=='+'||cprev=='-'||cprev=='*'||cprev=='/'){ 95 oper = oper.substring(0, i)+"@"+oper.substring(i+1); 96 } 97 } 98 } 99 } 100 return oper; 101 } 102 /** 103 * 完成带括弧的算数表达式运算 104 */ 105 public String calcbra(String oper){//从表达式中查找左括弧 106 int leftIndex = oper.lastIndexOf('('); 107 if(leftIndex==-1){//没有左括弧,调用calc直接运算 108 return calc(oper); 109 }else{//有括弧 110 //获取该括弧右侧的第一个右括弧 111 int rightIndex = oper.indexOf(')', leftIndex); 112 if(rightIndex==-1){ 113 throw new RuntimeException("表达式语法错误"); 114 }else{ 115 String exp = oper.substring(leftIndex+1, rightIndex); 116 //将表达式计算 117 String result = calc(exp); 118 oper = oper.substring(0,leftIndex)+result+oper.substring(rightIndex+1); 119 return calcbra(oper); 120 } 121 } 122 } 123 }
d.测试运行
step1:
-n 题目数
-o 题目输出文件名
-d 难度值
-r 数的范围
step2:
使出浑身解数,无奈解不出
step3:
-e 题目文件名
-a 计算结果文件名
-g 成绩统计结果文件名
step4:
回答错误相关提示
e.心得体会
分数的功能没有实现,题目重复的功能也没有实现。 不忘初心继续前行吧。
代码:http://git.oschina.net/lanchaohao/Javashow/
PSP2.1 | Personal Software Process Stages | Time Senior Student | Time | |
Planning | 计划 | 20 | 5 | |
· Estimate | 估计这个任务需要多少时间 | 300 | 450 | |
Development | 开发 | 240 | 320 | |
· Analysis | 需求分析 (包括学习新技术) | 6 | 10 | |
· Design Spec | 生成设计文档 | 5 | 6 | |
· Design Review | 设计复审 | 4 | 6 | |
· Coding Standard | 代码规范 | 3 | 3 | |
· Design | 具体设计 | 10 | 12 | |
· Coding | 具体编码 | 36 | 21 | |
· Code Review | 代码复审 | 7 | 9 | |
· Test | 测试(自我测试,修改代码,提交修改) | 13 | 10 | |
Reporting | 报告 | 5 | 3 | |
· | 测试报告 | 3 | 2 | |
· | 计算工作量 | 2 | 1 | |
· | 并提出过程改进计划 | 3 | 3 | |