- 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
广告