java中缀表达式转后缀表达式

四则运算是栈的重要应用之一

中缀表达式转后缀表达式(逆波兰算法)过程

  1. 从左到右遍历中缀表达式
  2. 数字直接输出为后缀表达式一部分
  3. 如果是符号,则判断与栈顶元素的优先级
  4. 高于栈顶元素优先级直接入栈
  5. 低于或等于栈顶优先级栈顶元素出栈并输出为后缀表达式一部分(注意这里是递归比较栈顶元素的优先级并出栈),最后将当前元素入栈
    直到遍历完中缀表达式,最终输出后缀表达式

下面是自己的实现源码

package com.yhq.demospringboot;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * yanghq
 * 2018/3/12
 */
public class PreToAfterUtil {

private static String leftChar = "(";
private static String rightChar = ")";
private static Map<String, Integer> operationSymbolMap = new HashMap<>();

static {
        //初始化符号和优先级
        operationSymbolMap.put(")",00); //右括号需匹配左括号,故优先级最低
        operationSymbolMap.put("+",10);
        operationSymbolMap.put("-",10);
        operationSymbolMap.put("*",20);
        operationSymbolMap.put("/",20);
        operationSymbolMap.put("(",30);
}

/**
 * 中缀表达式转化为后缀表达式
 * @param strings
 * @return
 */
public Queue parsePre(String[] strings) {
        Stack<String> preStack = new Stack<String>();
        Queue<String> queue = new LinkedBlockingQueue();
        int i = 0;
        while(i<strings.length && Objects.nonNull(strings[i])) {
                if(StringUtils.isNumeric(strings[i])) {
                        queue.add(strings[i]);
                }else if(StringUtils.isNotEmpty(strings[i])) {
                        if(preStack.isEmpty()) {
                                preStack.push(strings[i]);
                        } else {
                                String top = preStack.pop();
                                if(comparePriority(strings[i], top) < 0) {
                                        if(top.equals(leftChar)) {
                                                preStack.push(top);
                                                preStack.push(strings[i]);
                                        }else if(strings[i].equals(rightChar)) {
                                                appendTo(queue, top);
                                                preStack.pop();
                                        } else{
                                                appendTo(queue, top);
                                                popPre(preStack, strings[i], queue);
                                                preStack.push(strings[i]); //当前元素入栈
                                        }
                                } else {
                                        preStack.push(top);
                                        preStack.push(strings[i]);
                                }
                        }
                }
                i++;
        }
        while (!preStack.isEmpty()) {
                queue.add(preStack.pop());
        }
        return queue;
}

/**
 * 递归比较当前元素与栈顶元素优先级
 * @param preStatck
 * @param charTemp
 * @param queue
 */
public void popPre(Stack<String> preStatck, String charTemp, Queue queue) {
        if(!preStatck.isEmpty()) {
                String top = preStatck.pop();
                if(comparePriority(charTemp, top) <= 0) {
                        //低于栈顶元素,成为后缀表达式一部分
                        appendTo(queue, top);
                        popPre(preStatck, charTemp, queue);
                } else {
                        preStatck.push(top);
                }
        }
}

private void appendTo(Queue queue, String s) {
        if(!s.equals(leftChar) && !s.equals(rightChar)) {
                queue.add(s);
        }
}

/**
 * 比较优先级
 * @param start
 * @param to
 * @return
 */
private int comparePriority(String start, String to) {
        return operationSymbolMap.get(start).compareTo(operationSymbolMap.get(to));
}

/**
 * 计算后缀表达式结果
 * @param queue
 * @return
 */
public int computeResult(Queue<String> queue) {
        int result = 0;
        if(Objects.isNull(queue)) {
                return result;
        }
        String s = queue.poll();
        Stack<Integer> stack = new Stack();
        while(Objects.nonNull(s)) {
                if(StringUtils.isNumeric(s)) {
                        stack.push(Integer.valueOf(s));
                }else if(!StringUtils.isEmpty(s)) {
                        int first = 0;
                        int second = 0;
                        switch (s) {
                                case "+" :
                                        first = stack.pop();
                                        second = stack.pop();
                                        result = first + second;
                                        stack.push(result);
                                        break;
                                case "-" :
                                        first = stack.pop();
                                        second = stack.pop();
                                        result = second - first;
                                        stack.push(result);
                                        break;
                                case "*" :
                                        first = stack.pop();
                                        second = stack.pop();
                                        result = first * second;
                                        stack.push(result);
                                        break;
                                case "/" :
                                        first = stack.pop();
                                        second = stack.pop();
                                        result = second/first;
                                        stack.push(result);
                                        break;
                        }
                }
                s = queue.poll();
        }
        return result;
}

/**
 * 测试
 * @param args
 */
public static void main(String[] args) {
        String[] pre = new String[]{"8","+","(","6","-","1",")","*","2","+","10","/","2"};
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < pre.length; i++) {
                sb.append(pre[i]);
        }
        System.out.println("前缀表达式:" + sb.toString());
        Queue queue = new PreToAfterUtil().parsePre(pre);
        System.out.println("后缀表达式:" + queue.toString());
        System.out.println("后缀表达式计算结果:" + new PreToAfterUtil().computeResult(queue));
}

}

输出结果展示
前缀表达式:8+(6-1)2+10/2
后缀表达式:[8, 6, 1, -, 2,
, +, 10, 2, /, +]
后缀表达式计算结果:23

原文地址:http://blog.51cto.com/11290909/2085571

时间: 2024-10-01 11:48:08

java中缀表达式转后缀表达式的相关文章

Java版 中缀表达式转换为后缀表达式并求结果

基础知识 平时我们所说的一个算术表达式,例如:9+(3-1)*3+10/2即为中缀表达式,然而计算机无法计算中缀表达式的值,这是因为计算机无法进行带有左右括号和运算符的优先级这种混合运算.后缀表达式(又称 逆波兰式)的使用解决了上述问题. 上述的算术表达式的后缀表达式为:9 3 1 - 3 * + 10 2 / + 算法思想 如何计算上述后缀表达式的结果呢? 答案:从左到右扫描上述后缀表达式,然后: 1. 遇到数字入栈 2. 遇到运算符 将栈顶的前两个元素出栈,然后计算结果,并将计算的结果入栈

中缀表达式转后缀表达式(Java代码实现)

后缀表达式求值 后缀表达式又叫逆波兰表达式,其求值过程可以用到栈来辅助存储.例如要求值的后缀表达式为:1 2 3 + 4 * + 5 -,则求值过程如下: 遍历表达式,遇到数字时直接入栈,栈结构如下 2. 接着读到 “+”操作符,则将栈顶和次栈顶元素出栈与操作符进行运算,执行 2 + 3操作,并将结果5压入栈中,此时栈结构如下 3.  继续读到4,是数字则直接压栈,此时栈结构如下 4. 继续向后读取,此时读取到操作符“*”,则将栈顶和次栈顶元素出栈与操作符进行运算,即执行 5 * 4 ,然后将结

数据结构Java实现06----中缀表达式转换为后缀表达式

数据结构Java实现06----中缀表达式转换为后缀表达式 本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则),如:2 1 + 3 *.又比如3+(6-4/2)*5=23的后缀表达式为:3642/-5*+# (#符号为结束符

中缀表达式转为后缀表达式

** * 中缀表达式转后缀表达式 * * 作用:将一长串计算表达式转换为计算机易于操作的字符序列,用于计算器的设计 *  * 参与转换运算符 * +-/*()^% * * * 使用StringBuilder来保存转换出的后缀表达式 * 使用栈来操作运算符 * * * 转换原则 * 1.上述字符中()没有优先级值,+-优先级值为1,/*%优先级值为2,^优先级值为3 * 2.对于一个待计算的表达式,从左向右逐个检查每个字符 * 3.遇到数字,直接append到StringBuilder * 4.遇

栈的应用之中缀表达式转后缀表达式

1,中缀表达式的定义及为什么要将中缀表达式转换为后缀表达式? 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间.中缀表达式是人们常用的算术表示方法. 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值.对计算机来说,计算前缀或后缀表达式的值要比中缀表达式简单. 比如,计算机计算后缀表达式的过程如下----后缀表达式的计算机求值: 从左

数据结构中缀表达式转后缀表达式以及后缀转中缀表达式

最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要.为什么要学,可以看看这位博友的认识http://blog.csdn.NET/sdkfjksf/article/details/54380659 直入主题:将中缀表达式转为后缀表达式 以及将后缀表达式转为前缀表达式的实现. 关于后缀转中缀,中缀转后缀的理论介绍,请先阅读其互转的理论知识,或者我转发的这篇文章,这里不再累赘,最好参考<数据结构与算法描述Java语言版>,接下来将会用java写. 一.首先,怎么实现中缀表达式

算数表达式求值(中缀表达式转后缀表达式并求值)

中缀表达式转后缀表达式的规则:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出.5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)6.最终将栈中的元素依次出栈,输出 具体代码实现: 第一步:中缀表达式转后缀表达式 1 package data.st

ZH奶酪:Python 中缀表达式转换后缀表达式

实现一个可以处理加减乘数运算的中缀表达式转换后缀表达式的程序: 一个输入中缀表达式inOrder 一个输出池pool 一个缓存栈stack 从前至后逐字读取inOrder 首先看一下不包含括号的: (1)操作数:直接输出到pool (2)操作符:判断当前操作符与stack[top]操作符的优先级 <1>当前操作符优先级高于stack[top]:将当前操作符添加到stack中: <2>当前操作符优先级低于或等于stack[top]:从stack[top]开始出栈,直到stack[to

经典白话算法之中缀表达式和后缀表达式

一.后缀表达式求值 后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储. 假定待求值的后缀表达式为:6  5  2  3  + 8 * + 3  +  *,则其求值过程如下: (1)遍历表达式,遇到的数字首先放入栈中,依次读入6 5 2 3 此时栈如下所示: (2)接着读到"+",则从栈中弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中. (3)然后读到8(数字入栈),将其直接放入栈中. (4)读到"*",弹出8和5,执行8*5,并将结果40压入栈中