实现调车场算法的Java程序
分流码算法用于将中缀符号转换为反向波兰符号。后缀表示法也称为反向波兰表示法 (RPN)。该算法被命名为“调车场”,因为它的活动类似于铁路调车场。它是一种表示表达式的方法,其中运算符符号放置在被操作的参数之后。波兰表示法,其中运算符出现在操作数之前。澳大利亚哲学家和计算机科学家建议将运算符放在操作数之后,因此创建了反向波兰符号。 Dijkstra 开发了这个算法
代表和解释:
不需要括号来表示术语的评估顺序或分组。 RPN 表达式只是从左到右计算,这大大简化了计算机程序中表达式的计算。以算术表达式为例。
从左到右解释可以执行以下两个执行
- 如果该值出现在表达式中的下一个,则将当前值推入堆栈。
- 现在,如果接下来出现运算符,则从堆栈中弹出最顶部的两个元素,执行操作并将结果推回堆栈中。
运算符的优先顺序是: ^ 3 / 2 * 2 + 1 – 1Operator Order of precedence
说明: RPN 表达式会产生 2 和 3 的和,即 5:2 3 +
Input: (3+4)*5
Output: 3×4+5*
This is the postfix notation of the above infix notation
涉及的概念:Function of stacks Actions performed in the stacks push() To insert an element in the stack pop() To remove the current topmost element from the stack peek() To fetch the top element of the stack isEmpty() To check if the stack is empty or not IsFull() To check if the stack is empty or not
例子:
Infix Notation: a+b*(c^d-e)^(f+g*h)-i
Postfix Notation: abcd^e-fgh*+^*+i-
算法: AE 是用中缀符号写的算术表达式 PE 将是 AE 的后缀表达式
- 将“(”推入堆栈,并在AE末尾添加“)”。
- 从左到右扫描AE,对AE的每个元素重复步骤3到6,直到Stack为空。
- 如果遇到操作数,则将其附加到 PE。
- 如果遇到左括号,则将其压入堆栈。
- 如果遇到运算符,则: 重复从 Stack 中弹出并附加到 PE 的每个具有与运算符相同或更高优先级的运算符。向 Stack 添加一个运算符。 [如果结束]
- 如果遇到右括号,则: 重复从堆栈中弹出并将每个运算符附加到 PE,直到遇到左括号。删除左括号。 [如果结束] [如果结束]
- 克×小时
对下面给出的两个示例应用上述相同的算法:
Example 1 : Applying Shunting yard algorithm on the expression “1 + 2”
Step 1: Input “1 + 2”
Step 2: Push 1 to the output queue
Step 3: Push + to the operator stack, because + is an operator.
Step 4: Push 2 to the output queue
Step 5: After reading the input expression, the output queue and operator stack pop the expression and then add them to the output.
Step 6: Output “1 2 +”
Example 2: Applying the Shunting yard algorithm on the expression 5 + 2 / (3- 8) ^ 5 ^ 2 Token Action Stack output 5 “5” add token to output 5 + Push token to stack + 5 2 “2” add token to output + 5 2 / Push token to stack +/ 5 2 ( Push token to stack +/( 5 2 3 “3” add token to output +/( 5 2 3 – Push token to stack +/(- 5 2 3 8 “8” add token to output +/(- 5 2 3 8 ) Pop stack to output +/ 5 2 3 8 – ^ Push token to stack +/^ 5 2 3 8 – 5 “5” add token to output +/^ 5 2 3 8 – 5 ^ Push token to stack +/^ 5 2 3 8 – 5^ 2 “2” add token to output +/^ 5 2 3 8 – 5 ^ 2 End Pop whole stack 5238-5^2^/+
实施:调车场算法
Java
// Java Implemention of Shunting Yard Algorithm
// Importing stack class for stacks DS
import java.util.Stack;
// Importing specific character class as
// dealing with only operators and operands
import java.lang.Character;
class GFG {
// Method is used to get the precedence of operators
private static boolean letterOrDigit(char c)
{
// boolean check
if (Character.isLetterOrDigit(c))
return true;
else
return false;
}
// Operator having higher precedence
// value will be returned
static int getPrecedence(char ch)
{
if (ch == '+' || ch == '-')
return 1;
else if (ch == '*' || ch == '/')
return 2;
else if (ch == '^')
return 3;
else
return -1;
}
// Method converts given infixto postfix expression
// to illustrate shunting yard algorithm
static String infixToRpn(String expression)
{
// Initialising an empty String
// (for output) and an empty stack
Stack stack = new Stack<>();
// Initially empty string taken
String output = new String("");
// Iterating ovet tokens using inbuilt
// .length() function
for (int i = 0; i < expression.length(); ++i) {
// Finding character at 'i'th index
char c = expression.charAt(i);
// If the scanned Token is an
// operand, add it to output
if (letterOrDigit(c))
output += c;
// If the scanned Token is an '('
// push it to the stack
else if (c == '(')
stack.push(c);
// If the scanned Token is an ')' pop and append
// it to output from the stack until an '(' is
// encountered
else if (c == ')') {
while (!stack.isEmpty()
&& stack.peek() != '(')
output += stack.pop();
stack.pop();
}
// If an operator is encountered then taken the
// further action based on the precedence of the
// operator
else {
while (
!stack.isEmpty()
&& getPrecedence(c)
<= getPrecedence(stack.peek())) {
// peek() inbuilt stack function to
// fetch the top element(token)
output += stack.pop();
}
stack.push(c);
}
}
// pop all the remaining operators from
// the stack and append them to output
while (!stack.isEmpty()) {
if (stack.peek() == '(')
return "This expression is invalid";
output += stack.pop();
}
return output;
}
// Main driver code
public static void main(String[] args)
{
// Considering random infix string notation
String expression = "5+2/(3-8)^5^2";
// Printing RPN for the above infix notation
// Illustrating shunting yard algorithm
System.out.println(infixToRpn(expression));
}
}
5238-5^2^/+
- 时间复杂度:O(n) 这个算法需要线性时间,因为我们只遍历表达式一次,pop 和 push 只需要 O(1)。
- 空间复杂度:O(n),因为我们使用大小为 n 的堆栈,其中 n 是表达式的长度。