2.四则运算03

题目
老师提出了新的要求:
1、学生写的程序必须能判定用户的输入答案是否正确,
例如程序输出:20 – 5 = ?用户输入15,那么程序就会反馈正确,然后继续出题。直到 30 道题目结束,程序最后告诉用户作对了几道题。
2、程序必须能处理四种运算的混合算式;
20 – 5 * 2 =?           正确答案是10.
20– 5 * 2 + 9 / 3 = ?   正确答案是13
注意:
连续的减法和除法,应该遵守左结合的规定。
连续除法要打括号,否则会引起歧义
设计思想:
1.    用二叉树,生成数字和符号(每个叶子节点都是数字,每个父节点都是符号)
2.    正确的优先级'('')'>'*''/'>'+''-'

假设待去括号的表达式为 (m1 op1 n1) op (m2 op2 n2) 这里m1、n1、m2、m2可能自身就是个表达式,也可能是数字,op、op1、op2为运算符

                1、若op'/',则 (m2 op2 n2)的括号必须保留;

                2、若op'*''-',如果op2'+''-',则(m2 op2 n2)的括号必须保留;

               3、若op'*''/',如果op1'+''-',则(m1 op1 n1)的括号必须保留;

              4除此之外,去掉括号不影响表达式的计算顺序。

3.    判断是否正确:(int 输入=String结果)涉及String转换为int int n=Integer.parseInt(结果);  输入=n.                

4.    完成时间

代码:

package yunsuan04;

 

import java.util.*;//swing.//JOptionPane;

 

public class Test

{

    public static void main(String args[])

    {

       System.out.println("欢迎使用本系统,本系统自动产生四则运算表达式.");

       //JOptionPane.showMessageDialog(null,"欢迎使用本系统,本系统自动产生四则运算表达式。");

        int count1=0;//答对的题目个数

         int count2=0;//答错的题目个数

         boolean flag;//判断答案的对错*/

         double time1=System.currentTimeMillis();

      

        BinaryTree bTree; 

       

        for(int i = 0; i < 10; i++)

        { 

            bTree = new BinaryTree(2); 

            bTree.createBTree(); 

            String result = bTree.CalAndVal();

            int n=Integer.parseInt(result);

            System.out.println(bTree.toString() + "=" + "答案:");//result);

            Scanner in=new Scanner(System.in);

            int d=in.nextInt();

           if(d==n)

            {

           flag=true;

           System.out.println("恭喜你,答对啦!");

           ++count1;

           }

          else{

           flag=false;

           ++count2;

           System.out.println("答错啦,再努力!");

                  }

          }

            double time2=System.currentTimeMillis();

          int time=(int)((time2-time1)/1000);

          

           

           if(count1>count2){

              System.out.println("成绩不错,继续保持!");

               }

              else{

               System.out.println("该努力啦,加油~~!");

               }

            System.out.println("答对的题有:"+count1+"个"+" "+"答错的题有:"+count2+"个"+" "+"所用时间为:"+time+"秒");//最后统计答对题数答错的题目的个数

                    }

    }

 

package yunsuan04;

import java.util.ArrayList; 

public class BinaryTree

{

    private TreeNode root; 

    private int num; 

    private ArrayList<TreeNode> opeList = new ArrayList<TreeNode>(); 

     

    public BinaryTree(int num){ 

        this.num = num; 

    } 

     

    public int getNum(){ 

        return num; 

    } 

     

    public void setNum(int num){ 

        this.num = num; 

    } 

     

    public void setTreeNode(TreeNode root){ 

        this.root = root; 

    } 

     

     

    /**

     * 获取最终的表达式,必须在CalAndVal()方法后调用

     * 

     * @return str

     */ 

    public String toString(){ 

        String str = root.toString(); 

        str = str.substring(1, str.length()-1); 

        return str; 

    } 

     

    /**

     * 计算并验证表达式

     * 

     * @return result

     */ 

    public String CalAndVal(){ 

        return root.getResult(); 

    } 

     

    /**

     * 计算二叉树的深度(层数) 

     * 

     * @return deep

     */ 

    public int getDeep(){ 

        int i = this.num; 

        int deep = 2; 

        while(i/2 > 0){ 

            deep++; 

            i /= 2; 

        } 

        return deep; 

    } 

     

    /**

     * 生成二叉树

     * 

     */ 

    public void createBTree(){ 

        TreeNode lchild, rchild, lnode, rnode; 

         

        if(num == 1){ 

            lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

            rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

            root = new TreeNode(String.valueOf(Ran.getOperator()), lchild, rchild); 

        } 

        else

            int num1 = 0; 

            int n = getDeep() - 3; 

            boolean[] place = Ran.getChildPlace(num); 

            root = new TreeNode(String.valueOf(Ran.getOperator()), null, null); 

            opeList.add(root); 

             

            for(int i = 0; i < n; i++){ 

                for(int j = 0; j < (int)Math.pow(2, i); j++, num1++){ 

                    lchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null); 

                    rchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null); 

                    opeList.get(j + num1).setChild(lchild, rchild); 

                    opeList.add(lchild); 

                    opeList.add(rchild); 

                } 

            } 

             

            for(int i = 0; i < place.length; i++){ 

                if(place[i]){ 

                    lnode  = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

                    rnode  = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

                    if(i%2 == 0){ 

                        lchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode); 

                        opeList.add(lchild); 

                        opeList.get(num1).setLchild(lchild); 

                    } 

                    else

                        rchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode); 

                        opeList.add(rchild); 

                        opeList.get(num1).setRchild(rchild); 

                    } 

                } 

                else

                    if(i%2 == 0){ 

                        lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

                        opeList.get(num1).setLchild(lchild); 

                    } 

                    else

                         

                        rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null); 

                        opeList.get(num1).setRchild(rchild); 

                    } 

                } 

                num1 = num1 + i%2; 

            } 

        } 

    } 

2

package yunsuan04;

import java.util.Random; 

public class Ran {

     /* 获取随机的符号

     * @return operator

     */ 

     

    public static char getOperator(){ 

        char operator = 0; 

        Random ran = new Random(); 

        int i = ran.nextInt(4); 

        switch(i){ 

            case 0: 

                operator = '+'; 

                break

            case 1: 

                operator = '-'; 

                break

            case 2: 

                operator = '*'; 

                break

            case 3: 

                operator = '/'; 

                break

        } 

        return operator; 

    } 

     

     

    /**

     * 根据输入的范围获取随机数

     * 

     * @param max

     * @return number

     */ 

     

    public static int getNumber(int max){ 

        int number = 0; 

        Random ran = new Random(); 

        number = ran.nextInt(max+1); 

        return number; 

    } 

     

    /**

     * 根据运算符的个数随机产生子节点的位置

     * 

     * @param num

     * @return childPlace

     */ 

     

    public static boolean[] getChildPlace(int num){ 

        int d = 0; 

        int size = 0, j=1; 

        while(num >= (int)Math.pow(2, j)){ 

            j++; 

        } 

        d = (int)Math.pow(2, j) - 1 - num; 

        size = (int)Math.pow(2, j-1); 

        boolean[] k = new boolean[size]; 

        for(int i = 0; i < size; i++){ 

            k[i] = true

        } 

        for(int i = 0; i < d; i++){ 

            Random ran = new Random(); 

            int f = ran.nextInt(size); 

            while(k[f] == false

            { 

                f = ran.nextInt(size); 

            } 

            k[f] = false

        } 

        return k; 

    } 

 

}

3

package yunsuan04;

 

public class TreeNode {

    private String str; 

    private TreeNode rchild = null

    private TreeNode lchild = null

     

    public TreeNode(String str){ 

        this.str = str; 

    } 

     

    public TreeNode(String str, TreeNode lchild, TreeNode rchild){ 

        this.str = str; 

        this.rchild = rchild; 

        this.lchild = lchild; 

    } 

     

    public void setChild(TreeNode lchild, TreeNode rchild){ 

        this.lchild = lchild; 

        this.rchild = rchild; 

    } 

     

    public TreeNode getRchild() {   

        return rchild;   

    }   

    public void setRchild(TreeNode rchild) {   

        this.rchild = rchild;   

    }   

    public TreeNode getLchild() {   

        return lchild;   

    }   

    public void setLchild(TreeNode lchild) {   

        this.lchild = lchild;   

    } 

     

    public String getStr(){ 

        return str; 

    } 

     

    /**

     * 获取每个节点的运算结果,并检验除法

     * 1)除数为0

     * 2)不能整除

     * 出现以上两种情况的话将该运算符转换成其他三种运算符

     *  

     * @return result

     */ 

    public String getResult(){ 

        if(hasChild()){ 

            switch(str){ 

                case "+": 

                    return String.valueOf(Integer.parseInt(getLchild().getResult()) + Integer.parseInt(getRchild().getResult())); 

                case "-": 

                    return String.valueOf(Integer.parseInt(getLchild().getResult()) - Integer.parseInt(getRchild().getResult())); 

                case "*": 

                    return String.valueOf(Integer.parseInt(getLchild().getResult()) * Integer.parseInt(getRchild().getResult())); 

                case "/": 

                    if(getRchild().getResult().equals("0")){ 

                        while(str.equals("/")){ 

                            str = String.valueOf(Ran.getOperator()); 

                        } 

                        return this.getResult(); 

                    } 

                    else if(Integer.parseInt(getLchild().getResult()) % Integer.parseInt(getRchild().getResult()) != 0){ 

                        while(str.equals("/")){ 

                            str = String.valueOf(Ran.getOperator()); 

                        } 

                        return this.getResult(); 

                    } 

                    else 

                        return String.valueOf(Integer.parseInt(getLchild().getResult()) / Integer.parseInt(getRchild().getResult())); 

            } 

        } 

        return str; 

    }      

     

    /**

     * 先对每个运算式添加括号,然后根据去括号法则,去掉多余的子式的括号

     * 

     * @return string

     */ 

    public String toString(){ 

        String Lstr = "", Rstr = "", Str = ""; 

        if(hasChild()){ 

            //右子树如果有孩子,说明右子树是一个表达式,而不是数字节点。 

            if(getRchild().hasChild()){                          

                //判断左邻括号的运算符是否为'/' 

                if(str.equals("/")){ 

                    //获取右子树的表达式,保留括号 

                    Rstr = getRchild().toString();               

                } 

                //判断左邻括号的运算符是否为'*'或'-' 

                else if(str.equals("*") || str.equals("-")){ 

                    //判断op是否为'+'或'-' 

                    if(getRchild().str.equals("+") || getRchild().str.equals("-")){  

                        Rstr = getRchild().toString();           

                    } 

                    else

                        //获取右子树的表达式,并且去括号  

                        Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);   

                    } 

                } 

                else

                    //右子树除此之外都是可以去括号的。 

                    Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);       

                } 

            } 

            else

                Rstr = getRchild().str; 

            } 

            //左子树的情况同右子树类似 

            if(getLchild().hasChild()){                                              

                if(str.equals("*") || str.equals("/")){ 

                    if(getLchild().str.equals("+") || getLchild().str.equals("-")){ 

                        Lstr = getLchild().toString(); 

                    } 

                    else

                        Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1); 

                    } 

                } 

                else

                    Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1); 

                } 

            } 

            else

                Lstr = getLchild().str; 

            } 

            //获取当前的运算式,并加上括号 

            Str = "(" + Lstr + str + Rstr + ")";                                     

        } 

        else

            //若没有孩子,说明是数字节点,直接返回数字 

            Str = str; 

        } 

        return Str; 

    } 

     

    public boolean hasChild(){ 

        if(lchild == null && rchild == null

            return false

        else 

            return true

    } 

}  

截图:

 

原文地址:https://www.cnblogs.com/xuemo/p/5323677.html