首页 > 代码库 > 第一章-第一题(小学生四则运算)--By郭青云
第一章-第一题(小学生四则运算)--By郭青云
1.项目需求
a) 除了整数以外,还要支持真分数的四则运算。 (例如: 1/6 + 1/8 = 7/24)
b) 让程序能接受用户输入答案,并判定对错。 最后给出总共 对/错 的数量。
c) 逐步扩展功能和可以支持的表达式类型,最后希望能支持下面类型的题目 (最多 10 个运算符,括号的数量不限制)
25 - 3 * 4 - 2 / 2 + 89 = ?
1/2 + 1/3 - 1/4 = ?
(5 - 4 ) * (3 +28) =?
d) 一次可以批量出 100 道以上的题目,保存在文本文件中, 并且保证题目不能重复,
2.项目实现
a)开发环境
开发工具:MyEclipse、jdk1.8、windows 7
开发语言:Java
b)项目设计
1)主要UML图
2)主要代码
a.判断两个数是否互质
1 public static boolean isCoprime(int m,int n){ 2 int a=0; 3 int b=0; 4 int c=0; 5 if(m > n) { 6 a = m; 7 b = n; 8 }else{ 9 a=n;10 b=m;11 }12 while((c = a % b) != 0) {13 a = b;14 b = c;15 }16 if(b==1){17 return true;18 }19 return false;20 }
b.分数约分
/** * @param exp 单个分数表达式 * @returned String 返回约分后的分数表达式 * */ public static String afterSimplify(String exp){ String[] num=exp.split("/"); int cop=Integer.parseInt(num[0]);//分子 int deno=Integer.parseInt(num[1]);//分母 if(cop==0){//分子为0 return "0"; } int max=0; while(max!=1){ max=maxMultiple(cop, deno);//返回cop、deno的最大公约数 cop/=max; deno/=max; } if(deno==1){ return cop+"";//分数值为1 }else{ return cop+"/"+deno;//化简后的分数 } }
c.中缀表达式转化为后缀表达式
/** * @param infix 中缀表达式 * @returned String 后缀表达式 * */ public static String infix2postfix(String infix){ String postfix=""; int length=infix.length(); Stack st = new Stack(); String c; for (int i = 0; i < length; i++){ c = infix.substring(i, i+1); if (c .equals("(")){ st.push(c); }else if (c.equals(")")){ while (!st.peek().equals("(")){ postfix+= (st.pop()+"#"); } st.pop(); }else{ try{ Integer.parseInt(c);//判断读到的字符是否为数字 for(int j=0;j<5;j++){//如读到数字,则继续向后读取,直到读到运算符为止 String c_temp=""; if((i+j+2)>length){//判断是否到达输入的字符串的结尾 break; } c_temp=infix.substring(i+j+1,i+j+2); try { Integer.parseInt(c_temp);//判断独到的字符是否为数字 c+=c_temp; continue; } catch (Exception e) { break; } } i+=(c.length()-1); postfix+= (c+"#"); }catch(Exception e){ while (!st.empty()&& (comparePri((String)st.peek(), c) >= 0)){ postfix += (st.pop()+"#"); } st.push(c); } } } while (!st.empty()){//输入栈中剩余的所有元素 postfix +=(st.pop()+"#"); } return postfix; } /** *@param op1 op2 运算符 *@return int op1、op2的优先级比较结果 * */ public static int comparePri(String op1, String op2){ if (op1 .equals("(")){ return -1; }else if (op1 .equals("+") || op1 .equals("-")){ if (op2.equals("*") || op2.equals("/")){ return -1; } }else if (op1 .equals("*") ||op1 .equals("/")){ if (op2 .equals("+") || op2 .equals("-")){ return 1; } } return 0; }
d.表达式求值(整式和分式)
/** * @param exp 四则运算表达式 * @return 表达式元算结果的最简(分数)形式 * */ public String calculate(String exp){ int a,b,result=0; String first,second,temp = ""; int first_cop,first_deno,second_cop,second_deno; Stack s=new Stack(); String[] c=exp.split("#"); //分式求值 if(exp.contains("/")){ for(int i=0;i<c.length;i++){ if(!(c[i].contains("+")||c[i].contains("-")||c[i].contains("*")||c[i].contains("/"))){ s.push(c[i]+"/1");//将整数化为分母为1的分数形式 continue; }else{ second=(String) s.pop(); first=(String) s.pop(); first_cop=Integer.parseInt(first.split("/")[0]);//第一个分数的分子 first_deno=Integer.parseInt(first.split("/")[1]);//第一个分数的分母 second_cop=Integer.parseInt(second.split("/")[0]);//第二个分数的分子 second_deno=Integer.parseInt(second.split("/")[1]);//第二个分数的分母 if(c[i].equals("+")){//分数相加 temp=(first_cop*second_deno+second_cop*first_deno)+"/"+(first_deno*second_deno); }else if(c[i].equals("-")){//分数相减 temp=(first_cop*second_deno-second_cop*first_deno)+"/"+(first_deno*second_deno); }else if(c[i].equals("*")){//分数相乘 temp=(first_cop*second_cop)+"/"+(first_deno*second_deno); }else if(c[i].equals("/")){//分数相除 temp=(first_cop*second_deno)+"/"+(first_deno*second_cop); } s.push(temp);//将计算结果压入栈中 } } //将最终结果约分后返回 return Simplify.afterSimplify((String) s.pop()); }else{ //整式求值 for(int i=0;i<c.length;i++){ try{ Integer.parseInt(c[i]);//判断是否为数字 s.push(c[i]); continue; }catch(Exception e){ b=Integer.parseInt((String) s.pop()); a=Integer.parseInt((String) s.pop()); if(c[i].equals("+")){ result=a+b; }else if(c[i].equals("-")){ result=a-b; }else if(c[i].equals("*")){ result=a*b; } s.push(result+""); } } } //返回整数运算结果 return result+""; }
e.随机生成纯整式、纯分式、混合表达式
if(type.equals("1")){//整式运算 for (int i = 0; i < count; i++) {//生成count个正式 questions.add(b.zhengshi(min, max)); } }else if(type.equals("2")){//分式运算 for (int i = 0; i < count; i++) {//生成count个分式 questions.add(b.fenshi(deno)); } }else if(type.equals("3")){//混合运算 for (int i = 0; i < count; i++) {//生成count个混合元算表达式 int length=r.nextInt(4)+3;//新加的符号个最最多为6个 String op,exp=""; for(int j=0;j<length;j++){ op=ops[r.nextInt(2)];//随机选取运算符号 ‘+‘或‘*‘ if(op.equals("+")){ if(r.nextInt(2)==1){ exp=exp+b.zhengshu(min, max)+"+"; }else{ exp=exp+b.fenshu(deno)+"+"; } }else if(op.equals("*")){ if(exp.length()==0){ exp=r.nextInt(9)+2+"+"; } if(r.nextInt(2)==1){//随机选取整式或整数 String item=b.zhengshi(min, max); while(item.contains("*")||item.contains("/")){ item=b.zhengshi(min, max); } item="("+item+")"; if((exp.substring(0,exp.length()-1).contains("+")||exp.substring(0,exp.length()-1).contains("-")) &&!exp.substring(0,exp.length()-1).contains("*") &&!exp.substring(0,exp.length()-1).contains("/")){ exp="("+exp.substring(0,exp.length()-1)+")*"+item+"+"; }else{ exp=exp.substring(0,exp.length()-1)+"*"+item+"+"; } }else{ String item=b.zhengshu(min, max); if((exp.substring(0,exp.length()-1).contains("+")||exp.substring(0,exp.length()-1).contains("-")) &&!exp.substring(0,exp.length()-1).contains("*") &&!exp.substring(0,exp.length()-1).contains("/")){ exp="("+exp.substring(0,exp.length()-1)+")*"+item+"+"; }else{ exp=exp.substring(0,exp.length()-1)+"*"+item+"+"; } } } } if(!exp.equals("")&&(exp.subSequence(exp.length()-1, exp.length()).equals("+"))){ exp=exp.substring(0,exp.length()-1);//剔除表达式末尾的加号 }
c)测试结果
1)整式运算
2)分式元算
3)混合运算
3.总结
目前各项需求已基本达成,实验结果也比较令人满意。但也有不足之处,比如:题目重复检测、题目生成规则优待有待改善等。这些问题将会在下一阶段逐步解决。
第一章-第一题(小学生四则运算)--By郭青云
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。