自动生成小学四则运算题目

自动生成小学四则运算题目

题目

具体内容如图所示

思路分析(题目分解)

1.输入数字自动生成四则运算的题目

①确定算式长度生成一个随机数(5-9) n
②循环n次
  出现能被2整除的数字则自动生成一个1-9以内的数字
  出现不能被2整除的数字则自动生成+-*/运算符(将来拓展()的加入)
  在除法时应该考虑不出现小数,所以要确定后面的数可以将前面生成的那个数整除
③判断当前算式的答案是否为复数,或者大于100 如果不满足前面的条件则将算式存入到list集合中,否则将循环数减1,重新循环。

2.求解四则运算的题目(考虑到堆栈和后缀表达式)

①生成两个堆栈,分别用来存储数字和运算符
②利用正则表达式将运算式进行拆解
③对各个分解后的结果进行遍历,如果是运算数就存入到运算数的栈中,如果是运算符就要进行优先级的判断,如果栈定的优先级如果大于当前这个要存入的运算符的话,就取出这个运算符和运算数中的后两个数字进行计算(注意:以为栈是先进后出,如果取出来的是/,那么后取出来的的数是被除数!)。如果出现”)“,则一直取出运算符栈和运算数栈中的内容,知道运算符栈取出的是”(“为止;
④遍历结束,将运算栈中的内容清空,返回结果值

代码展示

主函数:

public static void main(String[] args) throws Exception {
       System.out.println("请输入要生成的练习题数量:");
       Scanner scanner = new Scanner(System.in);
       Integer testCount = scanner.nextInt();
      List<String> tests= generateTest(testCount);
       int score=0;
       for (int i=0;i<tests.size();i++){
           System.out.println(tests.get(i));
           System.out.println("请输入您的答案:");
           if (getResult(tests.get(i))==scanner.nextDouble()){
               System.out.println("答案正确!");
               score++;
           }else{
               System.out.println("答案错误!");
           }
       }
       System.out.println("您的成绩为:"+score*100/testCount);

   }

生成题目函数

public  static  List<String> generateTest(int num) throws Exception {
        List<String> listTest =new ArrayList<>();
        for(int i=0;i<num;i++){
            StringBuffer sb=new StringBuffer();
            int lenth=rd.nextInt(3)+6;//生成一个5--9长度的算术题
            for (int j=0;j<lenth;j++){
                if (j%2==0) {
                    sb.append(rd.nextInt(9) + 1);//生成一个1-9的随机数
                }else{
                    switch (rd.nextInt(4)){
                        case 0:sb.append("+");break;
                        case 1:sb.append("-");break;
                        case 2:sb.append("*");break;
                        case 3:
                           //必须生成整数
                            while (true){
                                int t=rd.nextInt(9)+1;
                                if ( sb.charAt(sb.length() - 1)%t==0){
                                    sb.append("/"+t);
                                    j++;
                                    break;
                                }
                            };break;
                    }
                }
            }
            if((String.valueOf(sb.charAt(sb.length()-1))).matches("[+\\-*/]")) {
                sb.append((rd.nextInt(9) + 1));
            }
           if (getResult(sb.toString())<0||(rd.nextInt(9) + 1)>100){
               i--;
               continue;
           }

            listTest.add(sb.toString());
        }
        return listTest;

    }

计算结果

 /**
     * 用于计算加减法 可以直接调用
     * @param a1
     * @param a2
     * @param operator
     * @return
     * @throws Exception
     */
    private static double doubleCal(double a1, double a2, char operator) throws Exception {

        switch (operator) {

            case '+':
                return a1 + a2;
            case '-':
                return a1 - a2;
            case '*':
                return a1 * a2;
            case '/':
                return a1 / a2;
            default:
                break;
        }
        throw new Exception("illegal operator!");
    }

    /**
     * 优先级的运算 判断出栈入栈
     * @param s
     * @return
     * @throws Exception
     */
    private static int getPriority(String s) throws Exception {

        if (s==null){
            return 0;
        }else if(s.equals("(")){
            return 1;
        }else if (s.equals("*")|| s.equals("/")){
            return 3;
        }else if(s.equals("+") ||s.equals("-")){
            return 2;
        }else{
            throw new Exception("非法操作!");
        }
    }

    /**
     * 获取结果
     * @param s
     * @return
     * @throws Exception
     */
    public static double getResult(String s) throws Exception {
        Stack<Double> Number=new Stack<>();
        Stack<String> Operator=new Stack<>();
        Operator.add(null);
        Pattern p= compile("\\d|[+\\-*/()]");
        Matcher m=p.matcher(s);
        while (m.find()){
            String temp=m.group();
            if (temp.equals("(")){//直接进入运算符栈
                Operator.add(temp);
            }else if (temp.equals(")")){
                String b=null;
                while (!(b=Operator.pop()).equals("(")){//直到出现)才截止
                    double number2=Number.pop();
                    double number1=Number.pop();
                    double res= doubleCal(number1,number2,b.charAt(0));
                    Number.add(res);
                }

            }else if (temp.matches("[+\\-*/]")){//判断是否为运算符
                if (Operator.peek()==null){//如果运算符中没有运算符则直接加入运算符栈
                    Operator.add(temp);
                    continue;
                }
                while (getPriority(temp)<=getPriority(Operator.peek())){//如果当前要入栈的运算优先级低于栈顶运算符的栈 那么就取出进行计算
                    double number2=Number.pop();
                    double number1=Number.pop();
                    String op=Operator.pop();
                    Number.add(doubleCal(number1,number2,op.charAt(0))) ;
                }
                Operator.add(temp);

            }else{
                Number.add(Double.parseDouble(temp));//运算数直接进入运算数栈
            }
        }
        while(Operator.peek()!=null){//循环结束 将运算栈中的内容清空
            double number2=Number.pop();
            double number1=Number.pop();
            Number.add(doubleCal(number1,number2,Operator.pop().charAt(0)));
        }
        return Number.pop();

    }

补充

后缀表达式解析:

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值