Student.java

package com.az.test.calc;

 

import java.util.Scanner;

 

 

import com.az.test.calc.CreateShiZi;

import com.az.test.calc.NiBoLanShi;

 

public class Student {

 

    public static void main(String[] args) {

        CreateShiZi createShiZi = new CreateShiZi();

        NiBoLanShi niBoLanShi = new NiBoLanShi();

        String[] fuHao = {"+","-","*","/"};

        Scanner input = new Scanner(System.in);

        System.out.println("请输入范围内的计算:");

        int m = input.nextInt();

        System.out.println("请输入要产生的题数:");

        int n = input.nextInt();

        String[] strArray = new String[n];

        System.out.println("\n题目\n");

        createShiZi.create(m, n, fuHao, strArray);

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

            String result = niBoLanShi.cal(strArray[i]);

            System.out.println(""+(i+1)+"题:"+strArray[i]);

            System.out.print("你的答案:");

            String yourAnswer = input.next();

            if (yourAnswer.equals(result)) {

                System.out.println("True\n");

            }else {

                System.out.println("False");

                System.out.println("正确答案:"+result+"\n");

            }

        }

    }

}

 

NiBoLanShi.java

package com.az.test.calc;

 

import java.util.List;

import java.math.BigDecimal;

import java.util.ArrayList;

import java.util.Stack;

 

public class NiBoLanShi {

    public static String cal(String str) {

        //对表达式进行预处理,并简单验证是否是正确的表达式

        //存放处理后的表达式

        List<String> list = new ArrayList<>();

        char[] arr = str.toCharArray();

        

        //存放数字临时变量

        StringBuffer tmpStr = new StringBuffer();

        for (char c : arr) {

            //如果是数字或小数点,添加到临时变量中

            if (c>='0' && c<='9') {

                tmpStr.append(c);

            }else if(c=='.') {

                if(tmpStr.indexOf(".")>0) {

                    throw new RuntimeException("非法字符");

                }

                tmpStr.append(c);

            }

            

            //如果是加减乘除或者括号,将数字临时变量和运算符依次放入List中

            else if (c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')') {

                if (tmpStr.length() > 0) {

                    list.add(tmpStr.toString());

                    tmpStr.setLength(0);

                }

                list.add(c + "");

            }

            else if (c==' ') {

                continue;

            }

            else {

                throw new RuntimeException("非法字符");

            }

        }

        if (tmpStr.length() > 0) {

            list.add(tmpStr.toString());

        }

        

        //初始化后缀表达式

        List<String> strList = new ArrayList<>();

        

        //运算过程中,使用了两次栈结构,

        //第一次是将中缀表达式转换成后缀表达式,第二次是计算后缀表达式的值

        Stack<String> stack = new Stack<>();

        

        //声明临时变量,存放栈元素

        String tmp;

        

        //将中缀表达式转换成后缀表达式

        for (String s : list) {

            //如果是左括号直接入栈

            if (s.equals("(")) {

                stack.push(s);

            }

            

            //如果是右括号,执行出栈操作,依次添加到后缀表达式中,直到出栈元素为左括号,左括号和右括号都不添加到后缀表达式中

            else if (s.equals(")")) {

                while (!(tmp = stack.pop()).equals("(")) {

                    strList.add(tmp);                    

                }

            }

            

            //如果是加减乘除,弹出所遇优先级大于或等于该运算符的栈顶元素(栈中肯定没有右括号,认为左括号的优先级最低),然后将该运算符入栈

            else if (s.equals("*") || s.equals("/")) {

                while(!stack.isEmpty()) {

                    //取出栈顶元素

                    tmp = stack.peek();//取出但不移除

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

                        stack.pop();

                        strList.add(tmp);

                    }

                    else {

                        break;

                    }

                }

                stack.push(s);

            }

            else if (s.equals("+") || s.equals("-")) {

                while(!stack.isEmpty()) {

                    //取出栈顶元素

                    tmp = stack.peek();

                    if (!tmp.equals("(")) {

                        stack.pop();

                        strList.add(tmp);

                    }

                    else {

                        break;

                    }

                }

                stack.push(s);

            }

            

            //如果是数字,直接添加到后缀表达式中

            else {

                strList.add(s);

            }

        }

        

        //最后依次出栈,放入后缀表达式中

        while (!stack.isEmpty()) {

            strList.add(stack.pop());

        }

        

        //计算后缀表达式的值

        Stack<BigDecimal> newStack = new Stack<>();

        for (String s : strList) {

            //若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符的左边

            //运算后的结果再进栈,直到后缀表达式遍历完毕

            if (s.equals("*") || s.equals("/") || s.equals("+") || s.equals("-")) {

                BigDecimal b1 = newStack.pop();

                BigDecimal b2 = newStack.pop();

                switch (s) {

                case "+":

                    newStack.push(b2.add(b1));

                    break;

                case "-":

                    newStack.push(b2.subtract(b1));

                    break;

                case "*":

                    newStack.push(b2.multiply(b1));

                    break;

                case "/":

                    newStack.push(b2.divide(b1, 9, BigDecimal.ROUND_HALF_UP));

                    break;

                }

            }

            

            //如果是数字,入栈

            else {

                newStack.push(new BigDecimal(s));

            }

        }

        

        //最后,栈中仅有一个元素,就是计算结果

        return newStack.peek().toString();

    }

}

 

CreateShiZi.java

package com.az.test.calc;

 

 

public class CreateShiZi {

    public void create(int m, int n, String[] fuHao, String[] strArray) {

        String str = "";

        

        //随机生成式子

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

            str = "";

            int[] arr1 = new int[n];

            int[] arr2 = new int[n];

            arr2[i] = (int)(Math.random()*m+1);

            for(int j = 0; j < (int)(Math.random()*10+1); j++) {

                int order = (int)(Math.random()*4);

                arr1[j] = (int)(Math.random()*m+1);

                str = str + arr1[j] + fuHao[order];

            }

            str = str + arr2[i];

            strArray[i] = str;

            System.out.println(""+(i+1)+"题:"+str);

            arr1 = null;

            arr2 = null;

        }

        System.out.println("\n");

    }

}

 

 

posted on 2020-06-11 17:31  迎新  阅读(83)  评论(0编辑  收藏  举报