首页 > 代码库 > 第一章-第一题(小学生四则运算)--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郭青云