字首表示式、中綴表示式、字尾表示式
阿新 • • 發佈:2019-02-11
中綴表示式就是我們日常看到的數學表示式:比如(2+4)*2,對於人類來說很直觀,但是對於計算機而言,這種表示式很不容易理解。於是就有了字首表示式和字尾表示式。
字首表示式
字首表示式是指將操作符放在前面,然後再放置運算元,比如對前面表示式而言,字首表示式為*、+、2、4、2;
字尾表示式
字尾表示式是指將先放運算元,然後再放操作符,比如對簽名表示式而言,字尾表示式為2、4、+、2、*
可以總結出規律,字首表示式和字尾表示式的操作符順序是相反的,而運算元的順序是相同的。
為什麼計算機對字尾表示式(字首)比較方便
我們看到字首表示式中不存在諸如括號改變優先順序的符號,事實上,通過字首表示式和字尾表示式可以很容易構造一顆運算樹,通過該運算樹,可以使用遞迴的方式很方便計算表示式,比如該運算式構成的樹為:
然後這裡,只需要int leftVal = calculate(root.left);int rightVal = calculate(root.right);然後可以計算出root值。
字首表示式轉樹
字首表示式如何變成一顆運算樹呢?
通過字首表示式,從後向前遍歷,當出現運算數時,將運算數變成Node物件壓棧,當出現運算子時,彈出棧中前兩個物件,然後再構成一顆子樹,入棧。。看程式碼吧
package com.dacas.converter;
import java.util.Stack;
/**
* Created by dave on 2016/4/6.
*/
public class ConvertPrefixExpressionToTree implements IConverter {
@Override
public TreeNode convert(String expression) {
char[] chars = expression.toCharArray();
Stack<TreeNode> nodes = new Stack<>();
for(int i = chars.length-1;i>=0;i--){
TreeNode root = new TreeNode(chars[i]);
if(!isValid(chars[i])){
TreeNode top1 = nodes.pop();
TreeNode top2 = nodes.pop();
root.setLeftNode(top1);
root.setRightNode(top2);
}
nodes.push(root);
}
return nodes.size() == 1?nodes.pop():null;
}
}
字尾表示式轉樹
字尾表示式和字首表示式構造樹的方式非常類似。只是這次從前向後遍歷。具體看程式碼
package com.dacas.converter; /**
* Created by dave on 2016/4/6.
*/
import java.util.Stack;
/**
* 將字尾表示式轉換成一個表示式樹
*/
public class ConvertPostExpressionToTree implements IConverter{
@Override
public TreeNode convert(String expression) {
Stack<TreeNode> nodes = new Stack<>();
char[] chars = expression.toCharArray();
for(char ch:chars){
TreeNode root = new TreeNode(ch);
if(!isValid(ch)) {
TreeNode top1 = nodes.pop();
TreeNode top2 = nodes.pop();
root.setLeftNode(top2);
root.setRightNode(top1);
}
nodes.push(root);
}
return nodes.size() == 1?nodes.pop():null;
}
}
中綴表示式轉字尾表示式
- 使用兩個棧,一個是操作符棧,一個是運算元棧;
- 遍歷中綴表示式,當一個字元為運算元時,壓入運算元棧;當為操作碼時,如果操作碼棧為空,直接壓入,如果為(,直接壓入操作碼棧,如果字元為),則出棧到(位置處,當操作碼棧不為空時,比較棧頂元素與當前元素的優先順序,如果當前元素優先順序小於等於棧頂元素,則出棧,否則入棧。
package com.dacas.converter;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
* Created by dave on 2016/4/6.
* 將中綴表示式轉換成字尾表示式
*/
public class ConvertMiddleExpressionToPostExpression{
static Map<Character,Integer> maps = new HashMap<>();
static {
maps.put('(',0);
maps.put('+',1);
maps.put('-',1);
maps.put('*',2);
maps.put('/',2);
}
public String convert(String midExpression){
Stack<Character> operators = new Stack<>();//操作符
Stack<String> operands = new Stack<>();//運算元
char[] chars = midExpression.toCharArray();
for(char ch:chars){
if(ch>='0' && ch<='9'){
operands.push(ch+"");
}else if(ch == '(') {
operators.push(ch);
}else if(ch == ')'){
char top;
while((top = operators.pop())!='('){
String ch1 = operands.pop();
String ch2 = operands.pop();
operands.push(ch2 + "," + ch1 + "," + top);
}
}else{//操作符
while (!operators.isEmpty() && comparePriority(operators.peek(), ch)) {//top >= ch,pop out
String ch1 = operands.pop();
String ch2 = operands.pop();
operands.push(ch2 + "," + ch1 + "," + operators.pop());
}
operators.push(ch);
}
}
while(!operators.isEmpty()){
String ch1 = operands.pop();
String ch2 = operands.pop();
operands.push(ch2+","+ch1+","+operators.pop());
}
return operands.pop();
}
private boolean comparePriority(char ch1,char ch2){
int int1 = maps.get(ch1);
int int2 = maps.get(ch2);
return int1 >= int2;
}
}
Main.java
import com.dacas.converter.*;
/**
* Created by dave on 2016/4/6.
*/
//資料結構與演算法分析第4章
public class Main {
public static void main(String[] args) {
performConvertPostExpressionToTree();
}
private static void performConvertPostExpressionToTree(){
/***********字尾表示式轉樹***********/
String postfix = "ab+cde+**";
IConverter postConverter = new ConvertPostExpressionToTree();
TreeNode postNode = postConverter.convert(postfix);
System.out.println(postNode);
/************字首表示式轉樹*****************/
String prefix = "-*+3456";
IConverter preConverter = new ConvertPrefixExpressionToTree();
TreeNode preNode = preConverter.convert(prefix);
System.out.println(preNode);
/****************中綴表示式轉字尾表示式**********************/
String midfix = "3*(4+5/2-2*3/8)/2";
ConvertMiddleExpressionToPostExpression midConverter = new ConvertMiddleExpressionToPostExpression();
String postfixExpression = midConverter.convert(midfix);
System.out.println(postfixExpression);
String[] strs = postfixExpression.split(",");
String newString = "";
for(String tmp:strs){
newString+=tmp+"";
}
TreeNode postNode2 = postConverter.convert(newString);
System.out.println(postNode2);
}
}