前缀表达式转后缀表达式,及后缀表达式计算器

前缀表达式转后缀表达式,及后缀表达式计算器[Java]

前缀表达式转后缀表达式

总体思路:

  1. 创建一个字符型的顺序栈栈和字符型的顺序表存放数字和运算符(顺序表和顺序栈创建参考1,2篇)。
  2. 将表达式符号两边插入空格(分割时就不会10分成1,0)后按空格分割。
  3. 遍历分割后的表达式:若遍历到数字则直接进顺序表;
  4. 若为运算符则先判断,栈若为空或栈顶是左括号或栈顶运算符优先级低于遍历到的运算符,则进栈,否则先栈内运算符出栈至顺序表直到满足进栈条件;若为左括号则直接进栈;若为右括号则栈内运算符一直出栈至顺序表直到栈顶为左括号,同时左括号出栈(不要了);
  5. 最后遍历顺序表,输出后缀表达式。

以(10+20/2*3)+2+8/4为例,输出结果为10 20 2 / 3 * + 2 + 8 4 / +

package p2.线性结构;
//前缀表达式转后缀表达式
public class InfixToSuffix {
    public static void main(String[] args) {
        String expression = "(10+20/2*3)+2+8/4";
        expression = infixtosuffix(expression);
        System.out.println(expression);
    }

    public static String infixtosuffix(String expression){ //开始进行前缀转后缀
        ArrayStack<String> opStack = new ArrayStack<>();
        ArrarList<String> suffixList = new ArrarList<>();
        expression =  insertblank(expression); //空格插入方法
        String[] tokens = expression.split(" ");
        for (String token:tokens){
            if (token.length() == 0){ //若token为空字符串则跳过,遍历下一个
                continue;
            }else if (isOperator(token)){ //当遍历到运算符,判断是进栈还是弹栈至顺序表
                while (true){
                    if (opStack.isEmpty() || opStack.peek().equals("(") || priority(opStack.peek()) < priority(token)){
                        opStack.push(token);
                        break;
                    }
                    suffixList.add(opStack.pop());
                }
            }else if (token.equals("(")){
                opStack.push(token);
            }else if (token.equals(")")){
                while (!opStack.peek().equals("(")){ //栈顶不为(的话就一直弹栈
                    suffixList.add(opStack.pop());
                }
                opStack.pop();
            }else if (isNumber(token)){
                suffixList.add(token);
            }else { //若为其他符号则抛出异常
                throw new IllegalArgumentException("wrong char:" + expression);
            }
        }
        while (!opStack.isEmpty()){
            suffixList.add(opStack.pop());
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < suffixList.size(); i++) {
            sb.append(suffixList.get(i));
            sb.append(' ');
        }
        return  sb.toString();
    }

    //判断运算符的优先级
    private static int priority(String token) {
        if (token.equals("+") || token.equals("-")) {
            return 0;
        }
        if (token.equals("*") || token.equals("/")) {
            return 1;
        }
        return -1;
    }

    //判断是否为数字
    private static boolean isNumber(String token) {
        return token.matches("\\d+");
    }

    //判断是否是运算符
    private static boolean isOperator(String token) {
        return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
    }

    //空格插入方法
    private static String insertblank(String expression){
        StringBuilder sb = new StringBuilder();
        for (int i = 0;i< expression.length();i++){
            char c = expression.charAt(i);
            if (c == '('|| c==')'|| c=='+' || c=='-' || c== '*' || c=='/'){
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            }else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

后缀表达式计算器

  1. 先将表达式转成后缀表达式(符号间已插入空格)
  2. 创建一个整形的顺序栈
  3. 遍历表达式:如果遍历到数字则直接进栈;如果是运算符则弹栈两个数字进行运算并入栈(后弹栈的运算时放前面)
  4. 最后返回数字栈弹栈的结果
package p2.线性结构;
//后缀表达式的计算器
public class SuffixCalculator {
    public static void main(String[] args) {
        String infixExpression = "(10+20/2*3)/2+8";
        String suffixExpression = InfixToSuffix.infixToSuffix(infixExpression);//调用InfixToSuffix类的infixToSuffix方法
        int result = evaluateSuffix(suffixExpression);
        System.out.println(result);
    }

    private static int evaluateSuffix(String expression) {
        ArrayStack<Integer> stack = new ArrayStack<>();
        String[] tokens = expression.split(" ");
        //10 20 2 / 3 * + 2 + 8 4 / +  
        for (String token : tokens) {
            if (token.length() == 0) {//若token为空字符串则跳过,遍历下一个
                continue;
            }
            if (isNumber(token)) {
                stack.push(new Integer(token));
            } else {
                processAnOperator(stack,token);//如果遇到运算符则弹栈两个数字运算,运算后再进栈
            }
        }
        return stack.pop();
    }

    private static void processAnOperator(ArrayStack<Integer> stack, String token) {
        int num1 = stack.pop();
        int num2 = stack.pop();
        if (token.equals("+")) {
            stack.push(num2 + num1);
        } else if (token.equals("-")) {
            stack.push(num2 - num1);
        } else if (token.equals("*")) {
            stack.push(num2 * num1);
        } else if (token.equals("/")) {
            stack.push(num2 / num1);
        }
    }

    private static boolean isNumber(String token) {
        return token.matches("\\d+");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值