- Java 資料結構與演算法 教程
- Java 資料結構與演算法 - 首頁
- Java 資料結構與演算法 - 概述
- Java 資料結構與演算法 - 環境搭建
- Java 資料結構與演算法 - 演算法
- Java 資料結構與演算法 - 資料結構
- Java 資料結構與演算法 - 陣列
- Java 資料結構與演算法 - 連結串列
- Java 資料結構與演算法 - 雙向連結串列
- Java 資料結構與演算法 - 迴圈連結串列
- Java 資料結構與演算法 - 棧
- 資料結構與演算法 - 表示式解析
- Java 資料結構與演算法 - 佇列
- Java 資料結構與演算法 - 優先佇列
- Java 資料結構與演算法 - 樹
- Java 資料結構與演算法 - 散列表
- Java 資料結構與演算法 - 堆
- Java 資料結構與演算法 - 圖
- Java 資料結構與演算法 - 搜尋技術
- Java 資料結構與演算法 - 排序技術
- Java 資料結構與演算法 - 遞迴
- Java 資料結構與演算法 有用資源
- Java 資料結構與演算法 - 快速指南
- Java 資料結構與演算法 - 有用資源
- Java 資料結構與演算法 - 討論
Java 資料結構與演算法 - 表示式解析
像 2*(3*4) 這樣的普通算術表示式,人類很容易解析,但對於演算法來說,解析這樣的表示式就比較困難了。為了簡化這個難度,可以使用兩步法來解析算術表示式。
將提供的算術表示式轉換為字尾表示法。
評估字尾表示法。
中綴表示法
普通的算術表示式遵循中綴表示法,其中運算子位於運算元之間。例如 A+B,其中 A 是第一個運算元,B 是第二個運算元,+ 是作用於這兩個運算元的運算子。
字尾表示法
字尾表示法與普通的算術表示式或中綴表示法不同,運算子位於運算元之後。例如,考慮以下示例
| 序號 | 中綴表示法 | 字尾表示法 |
|---|---|---|
| 1 | A+B | AB+ |
| 2 | (A+B)*C | AB+C* |
| 3 | A*(B+C) | ABC+* |
| 4 | A/B+C/D | AB/CD/+ |
| 5 | (A+B)*(C+D) | AB+CD+* |
| 6 | ((A+B)*C)-D | AB+C*D- |
中綴轉字尾轉換
在研究將中綴轉換為字尾表示法的方法之前,我們需要考慮中綴表示式求值的基本知識。
中綴表示式的求值從左到右開始。
記住優先順序,例如 * 的優先順序高於 +。例如
2+3*4 = 2+12.
2+3*4 = 14.
使用括號覆蓋優先順序,例如
(2+3)*4 = 5*4.
(2+3)*4= 20.
現在讓我們手動將簡單的中綴表示式 A+B*C 轉換為字尾表示式。
| 步驟 | 讀取的字元 | 已解析的中綴表示式 | 已生成的 字尾表示式 | 備註 |
|---|---|---|---|---|
| 1 | A | A | A | |
| 2 | + | A+ | A | |
| 3 | B | A+B | AB | |
| 4 | * | A+B* | AB | 由於 * 的優先順序高於 +,因此不能複製 +。 |
| 5 | C | A+B*C | ABC | |
| 6 | A+B*C | ABC* | 複製 *,因為有兩個運算元 B 和 C | |
| 7 | A+B*C | ABC*+ | 複製 +,因為有兩個運算元 BC 和 A |
現在讓我們使用棧將上述中綴表示式 A+B*C 轉換為字尾表示式。
| 步驟 | 讀取的字元 | 已解析的中綴表示式 | 已生成的 字尾表示式 | 棧內容 | 備註 |
|---|---|---|---|---|---|
| 1 | A | A | A | ||
| 2 | + | A+ | A | + | 將 + 運算子壓入棧中。 |
| 3 | B | A+B | AB | + | |
| 4 | * | A+B* | AB | +* | * 運算子的優先順序高於 +。將 * 運算子壓入棧中。否則,+ 將彈出。 |
| 5 | C | A+B*C | ABC | +* | |
| 6 | A+B*C | ABC* | + | 沒有更多運算元,彈出 * 運算子。 | |
| 7 | A+B*C | ABC*+ | 彈出 + 運算子。 |
現在讓我們看另一個例子,使用棧將中綴表示式 A*(B+C) 轉換為字尾表示式。
| 步驟 | 讀取的字元 | 已解析的中綴表示式 | 已生成的 字尾表示式 | 棧內容 | 備註 |
|---|---|---|---|---|---|
| 1 | A | A | A | ||
| 2 | * | A* | A | * | 將 * 運算子壓入棧中。 |
| 3 | ( | A*( | A | *( | 將 ( 壓入棧中。 |
| 4 | B | A*(B | AB | *( | |
| 5 | + | A*(B+ | AB | *(+ | 將 + 壓入棧中。 |
| 6 | C | A*(B+C | ABC | *(+ | |
| 7 | ) | A*(B+C) | ABC+ | *( | 彈出 + 運算子。 |
| 8 | A*(B+C) | ABC+ | * | 彈出 ( 運算子。 | |
| 9 | A*(B+C) | ABC+* | 彈出其餘運算子。 |
演示程式
現在我們將演示使用棧將中綴表示式轉換為字尾表示式,然後評估字尾表示式。
Stack.javapackage com.tutorialspoint.expression;
public class Stack {
private int size;
private int[] intArray;
private int top;
//Constructor
public Stack(int size){
this.size = size;
intArray = new int[size];
top = -1;
}
//push item on the top of the stack
public void push(int data) {
if(!isFull()){
//increment top by 1 and insert data
intArray[++top] = data;
}else{
System.out.println("Cannot add data. Stack is full.");
}
}
//pop item from the top of the stack
public int pop() {
//retrieve data and decrement the top by 1
return intArray[top--];
}
//view the data at top of the stack
public int peek() {
//retrieve data from the top
return intArray[top];
}
//return true if stack is full
public boolean isFull(){
return (top == size-1);
}
//return true if stack is empty
public boolean isEmpty(){
return (top == -1);
}
}
InfixToPostFix.java
package com.tutorialspoint.expression;
public class InfixToPostfix {
private Stack stack;
private String input = "";
private String output = "";
public InfixToPostfix(String input){
this.input = input;
stack = new Stack(input.length());
}
public String translate(){
for(int i=0;i<input.length();i++){
char ch = input.charAt(i);
switch(ch){
case '+':
case '-':
gotOperator(ch, 1);
break;
case '*':
case '/':
gotOperator(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
gotParenthesis(ch);
break;
default:
output = output+ch;
break;
}
}
while(!stack.isEmpty()){
output = output + (char)stack.pop();
}
return output;
}
//got operator from input
public void gotOperator(char operator, int precedence){
while(!stack.isEmpty()){
char prevOperator = (char)stack.pop();
if(prevOperator == '('){
stack.push(prevOperator);
break;
}else{
int precedence1;
if(prevOperator == '+' || prevOperator == '-'){
precedence1 = 1;
}else{
precedence1 = 2;
}
if(precedence1 < precedence){
stack.push(Character.getNumericValue(prevOperator));
break;
}else{
output = output + prevOperator;
}
}
}
stack.push(operator);
}
//got operator from input
public void gotParenthesis(char parenthesis){
while(!stack.isEmpty()){
char ch = (char)stack.pop();
if(ch == '('){
break;
}else{
output = output + ch;
}
}
}
}
PostFixParser.java
package com.tutorialspoint.expression;
public class PostFixParser {
private Stack stack;
private String input;
public PostFixParser(String postfixExpression){
input = postfixExpression;
stack = new Stack(input.length());
}
public int evaluate(){
char ch;
int firstOperand;
int secondOperand;
int tempResult;
for(int i=0;i<input.length();i++){
ch = input.charAt(i);
if(ch >= '0' && ch <= '9'){
stack.push(Character.getNumericValue(ch));
}else{
firstOperand = stack.pop();
secondOperand = stack.pop();
switch(ch){
case '+':
tempResult = firstOperand + secondOperand;
break;
case '-':
tempResult = firstOperand - secondOperand;
break;
case '*':
tempResult = firstOperand * secondOperand;
break;
case '/':
tempResult = firstOperand / secondOperand;
break;
default:
tempResult = 0;
}
stack.push(tempResult);
}
}
return stack.pop();
}
}
PostFixDemo.java
package com.tutorialspoint.expression;
public class PostFixDemo {
public static void main(String args[]){
String input = "1*(2+3)";
InfixToPostfix translator = new InfixToPostfix(input);
String output = translator.translate();
System.out.println("Infix expression is: " + input);
System.out.println("Postfix expression is: " + output);
PostFixParser parser = new PostFixParser(output);
System.out.println("Result is: " + parser.evaluate());
}
}
如果我們編譯並執行上述程式,它將產生以下結果:
Infix expression is: 1*(2+3) Postfix expression is: 123+* Result is: 5
廣告