4网页版四则运算

4

n  详细要求:

n  1、 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2

n  2、生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。

n  3、每道题目中出现的运算符个数不超过3个,括号不限。

n  4、程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。

n  例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。

n  3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。

n  5、把程序变成一个网页程序, 用户通过设定参数,就可以得到各种题目,并可实现在线答题并评判。

在第三次实验的基础上,老师又对此提出了新的要求,实现网页版四则运算。

设计思想:因为是网页版的所以就会使用jsp,html与java文件之间的数据交换

代码:

Test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.*" %>
    <% BinaryTree bTree; %>
    <% bTree = new BinaryTree(2);%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
		System.out.println("欢迎使用本系统,本系统自动产生四则运算表达式.");
		//JOptionPane.showMessageDialog(null,"欢迎使用本系统,本系统自动产生四则运算表达式。");
	    int count1=0;//答对的题目个数
	     int count2=0;//答错的题目个数
	     boolean flag;//判断答案的对错*/
	     double time1=System.currentTimeMillis();%>
	   <form action="BinaryTree.jsp" method="post">
    <center>
    <%  
       for(int i = 0; i < 10; i++)
        {  
            //这里
            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+"个"+"\n"+"答错的题有:"+count2+"个"+"\n"+"所用时间为:"+time+"秒");//最后统计答对题数答错的题目的个数
            %>
</body>
</html>

  

 

 

Ran.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.Random;"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>
<body>
<%
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;  
    }  
%>
</body>
</html>

  BinaryTree.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.ArrayList;" %>
    <%private TreeNode root;  
    private int num;  
    private ArrayList<TreeNode> opeList = new ArrayList<TreeNode>();  
      %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="TreeNode.jsp" method="post">
    <center>
<form action="BinaryTree.jsp" method="post">
    <center>
     <%
    {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;  
        }  
    }  
    %>

</body>
</html>

  TreeNode.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
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;  
    }  %>
</body>
</html>

 

截图:

 

总结:不出现重复,没有实现。有些地方没有转换好程序无法运行,一些功能不知道怎样实现,还需要继续学习

posted @ 2016-04-10 19:19  sunmei  阅读(316)  评论(0编辑  收藏  举报