7-2 求前缀表达式的值 (25 分)

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式:

输入在一行内给出不超过30个字符的前缀表达式,只包含+-*/以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式:

输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR

输入样例:

+ + 2 * 3 - 7 4 / 8 4

输出样例:

13.0

反思和思路:

 //前缀表达式的
        /**
         * 首先需要从右向左遍历,遇到数字就压栈
         *
         *  遇到符号把栈顶的前两个数字出栈
         * 
         * 然后把结果压入栈中
         * 循环操作
         */

此题一直以为是整数,想到用正则匹配数字发现有好多错误点,于是又思考了一下,于是是有小数,所以不能匹配整数,所以需要另外寻找一个方法来匹配数字,因为是只有数字和符号,那就是符号的相对面就是数字。所以我加入一个判断数字的方法:

!(attr[i].equals("-")||attr[i].equals("+")||attr[i].equals("/")||attr[i].equals("*"))
import java.util.Scanner;
 import java.util.Stack;public class Main {
    public static void main(String[] args) {
        
         Stack<Object>stack = new Stack<Object>(); //定义栈
         Scanner sr = new Scanner(System.in);
         String s = sr.nextLine();//输入字符串
         String attr[] = s.split(" "); //以空格分割字符串存进字符串中
         boolean temp = true; //定义一个临时变量
         int chars = 0; //用于记录符号数
         int num = 0; //用于记录数字的个数
         for(int i=attr.length-1;i>=0;i--) {
             try { //从右向左遍历,遇到数字压栈
                 if(!(attr[i].equals("-")||attr[i].equals("+")||attr[i].equals("/")||attr[i].equals("*"))) {
                     stack.push(Double.parseDouble(attr[i])); //转换为double类型的
                     num++; //记录数字个数
                 }else {  //遇到符号把栈顶的前两个数字出栈
                     double a = (Double)stack.pop();//出栈
                     double b = (Double)stack.pop();//出栈
                     chars ++;//字符的个数
                     double result = SymCal(a, b, attr[i]); //调用函数计算结果值
                     stack.push(result); //结果进栈
                 }
             }
             catch (Exception e) {
                 temp = true; //抛出的异常
                 
             }
             temp = false;
         }
         if (temp || !(num - 1 == chars) || stack.empty()) { //没有进入for循环 或者栈为空,或者符号不够
             System.out.println("ERROR");
         } else {
             double ans = (double) stack.pop(); //让最后一个结果出栈
             System.out.printf("%.1f\n",ans);
         }
         
     }
    public static double SymCal(double a, double b, String s) { //用于计算
         switch(s) {
         case "*":
             return a*b;
         case "/":
             return a/b;
         case "+":
             return a+b;
         case "-":
             return a-b;
         }
         return 0;
     }}

java 多词 前缀匹配 前缀表达式计算java_前缀表达式

注:此题有一个测试点一直过不去,调试了很长时间依旧不行,最后不得已放弃,望有大佬看见可以给出解答。 

ac代码:历经多少次调试终于把唯一的一个测试点过了:

java 多词 前缀匹配 前缀表达式计算java_Stack_02

 


import java.util.Scanner;
import java.util.Stack;

public class Main {

    public static void main(String[] args) {
        //前缀表达式的
        /**
         * 首先需要从右向左遍历,遇到数字就压栈
         *
         *  遇到符号把栈顶的前两个数字出栈
         *
         * 然后把结果压入栈中
         * 循环操作
         */
        Stack<Object>stack = new Stack<Object>();
        Scanner sr = new Scanner(System.in);
        String s = sr.nextLine();
        String regx = "[0-9]*"; //匹配数字
        String attr[] = s.split(" ");
        boolean temp = true;
        int chars = 0; //用于记录符号数
        int num = 0; //用于记录数字的个数
        for(int i=attr.length-1;i>=0;i--) {
                if(!(attr[i].equals("-")||attr[i].equals("+")||attr[i].equals("/")||attr[i].equals("*"))) {
                    stack.push(Double.parseDouble(attr[i]));
                    num++;
                }else {
                    double a = (Double)stack.pop();//出栈
                    double b = (Double)stack.pop();//出栈
                    if(attr[i].equals("/")&&b==0) {
                        temp=true;
                        break;
                    }
                    chars ++;
                    double result = SymCal(a, b, attr[i]); //调用函数计算结果值
                    stack.push(result); //结果进栈
                }
                temp=false;
            }

        if (temp || !(num - 1 == chars) || stack.empty()) { //没有进入for循环 或者栈为空,或者符号不够
            System.out.println("ERROR");
        } else {
            double ans = (double) stack.pop();
            System.out.printf("%.1f\n",ans);
        }

    }
    public static double SymCal(double a, double b, String s) {
        switch(s) {
            case "*":
                return a*b;
            case "/":
                return a/b;
            case "+":
                return a+b;
            case "-":
                return a-b;
        }
        return 0;
    }
}


两段代码唯一不同的也就是加了一个判断处理:当做除法时候需要判断分母不为零,否则java里面会自动变为无限大