用java求前缀表达式的值

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;
    }

}

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

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

 

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里面会自动变为无限大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值