中序表达式 to 后序表达式

将带有计算的优先级和括号的中序表达式变成符合某文法的后序表达式

  • 《编程导论(Java)·5.5.2》的参考资料
  • 解释器模式中或许需要的工具

直接上代码。

package intent.interpreter.calculator2;
import java.util.HashMap;
import java.util.Stack;
import tool.God;

public class Nothing{

    private static HashMap<Character,Integer> priority=new HashMap<Character,Integer>(){
        {
            put('+', 1);
            put('-', 1);
            put('/', 2);
            put('*', 2);
            put('(', 0);
        }
    };
    /**
     * 将带有计算的优先级和括号的中序表达式inOrder变成符合前述文法的后序表达式
     */

    static String inToPost(String inOrder) {
        Stack<Character> s = new Stack<>();
        String res = "";//postfix expression
        char temp ;//保存s.pop()
        char[] expr = inOrder.trim().toCharArray();
        for (char x :expr) {
            //如果是操作数,直接输出
            if ( !isOperator(x) && ( x!='(' ) && ( x!=')') ) {
                res = res + x;
            }else if (x=='(') {
                s.push(x);//入栈
            }else if (x==')') {//输出栈中的右操作符直到取出(。
                temp =  s.pop();
                while (temp!='(') {
                    res = res + temp;
                    temp =  s.pop();
                }
                temp = '\0';
            }else if (isOperator(x)) {//与栈顶操作符比较优先级
                if (!s.isEmpty()) {
                    temp = s.pop();
                    int prio1 = priority.get(temp);
                    int prio2 = priority.get(x);
                    while ( prio1 >= prio2 ) {
                        res = res + temp;
                        prio1 = -1;
                        if (!s.isEmpty()) {
                            temp =  s.pop();
                            prio1 = priority.get(temp);
                        }
                    }
                    if ((prio1 < prio2) && (prio1 != -1)){
                        s.push(temp);
                    }
                }
                s.push(x);
            }
        }// end for
        while (!s.isEmpty() ) {
            temp = s.pop();
            res = res + temp;
        }
        return res;
    }
    static boolean isOperator(char c) {
        return c=='+'||c=='-'||c=='*'||c=='/';
    }
    static void test(){
        String inOrder = "a+b*c-d";
        inOrder= (String)God.getValue("expression");
        System.out.println(" inOrder = "+inOrder);
        System.out.println(" postOrder = "+inToPost(inOrder));
    }
}

inOrder = a+b*c-d

postOrder = abc*+d-

inOrder = (a+b)*(c-d)

postOrder = ab+cd-*

inOrder = a+b/c*(c-d)

postOrder = abc/cd-*+

使用配置文件时:

#intent.interpreter.calculator2. Alph ={a|b|c|d}.Op={*|+|-}

#expression = (a+b)*(c-d)

#expression =a+b*c-d

expression = a+b/c*(c-d)

时间: 2024-11-06 07:45:15

中序表达式 to 后序表达式的相关文章

算法学习 - 表达树的建立(后缀表达式法),树的先序遍历,中序遍历,后序遍历

表达树就是根据后缀表达式来建立一个二叉树. 这个二叉树的每个叶子节点就是数,真祖先都是操作符. 通过栈来建立的,所以这里也会有很多栈的操作. 树的先序遍历,中序遍历,后序遍历的概念我就不讲了,不会的自行百度,不然也看不懂我的代码. 下面是代码: // // main.cpp // expressionTree // // Created by Alps on 14-7-29. // Copyright (c) 2014年 chen. All rights reserved. // #includ

中序表达式转后序表式式

中序表达式转后序表式式: 将中序表达式所有括号补全,然后将所有运算符向右移出无匹配的第一个右括号,去掉括号即为后序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移:(a(b(c(de)/)+)*)+ 去掉括号:abcde/+*+ 中序表达式转前序表式式: 将中序表达式所有括号补全,然后将所有运算符向左移出无匹配的第一个左括号,去掉括号即为前序表式式 举例: 原式:a+b*(c+d/e) 补全括号:(a+(b*(c+(d/e)))) 操作符右移

根据 中序遍历 和 后序遍历构造树(Presentation)(C++)

好不容易又到周五了,周末终于可以休息休息了.写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历.等等,我找一下链接出来...... 1127. ZigZagging on a Tree (30):https://www.patest.cn/contests/pat-a-practise/1127 突然想起以前学数据结构的时候如果给出一个中序遍历和一个后序遍历然后让你画出树的结构或求出先序遍历之类的题目,

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

根据前序遍历和中序遍历求后序遍历

根据前序遍历和中序遍历求后序遍历 一道HULU的笔试题(How I wish yesterday once more) 假设有棵树,长下面这个样子,它的前序遍历,中序遍历,后续遍历都很容易知道. PreOrder:         GDAFEMHZ InOrder:            ADEFGHMZ PostOrder:       AEFDHZMG 现在,假设仅仅知道前序和中序遍历,如何求后序遍历呢?比如,已知一棵树的前序遍历是"GDAFEMHZ",而中序遍历是"AD

根据前序和中序遍历求后序 /后序和中序求前序

给出一二叉树的前序遍历的顺序和中序遍历的顺序我们可以由此得出后序遍历的顺序,根据它们的访问顺序,前序遍历的第一个结点肯定是根结点,与之对应在中序遍历找到对应的根结点的位置,那么在中序遍历中,根结点的左边的元素都属于左子树的元素,根结点右边的元素都属于右子树的元素,之后把左子树当成一个继续操作,就这样可以推出整个树,继而求出后序遍历: #include<iostream> #include<cstdlib> #include<cstring> #include<cs

已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历

[题解整理]二分题 题目类型: 二分查找: 二分答案. 大致解题思路: 查找注意有序和返回值: 浮点数注意精度: 整数注意返回值,建议另外维护一个变量,用于储存可行解. 题目 分类 传送门 WA点 poj 2785 二分查找 题解 lightoj 1088 二分查找 题解 lightoj 1307 二分查找 题解 longlong poj 2456 整数二分答案 题解 poj 3104 整数二分答案 题解 poj 3258 整数二分答案 题解 poj 3273 整数二分答案 题解 lightoj

二叉树重建 - (先序遍历、中序遍历、后序遍历)

对于一棵二叉树T,我们可以递归定义它的先序遍历,中序遍历,后序遍历:  1.先序遍历  ( PreOrder(T) = T的根节点 + PreOrder(T的左子树) + PreOrder(T的右子树) ) 2.中序遍历  ( InOrder(T) = InOrder(T的左子树) + T的根节点 +  InOrder(T的右子树) ) 3.后序遍历  ( PostOrder(T) = PostOrder(T的左子树) + PostOrder(T的右子树)  + T的根节点 ) 其中,加号表

LintCode(72)中序遍历和后序遍历树构造二叉树

题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 /  \ 1    3 分析 递归解决. Python代码 """ Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None "&q

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点