使用两个堆栈的中缀到前缀转换
中缀:如果运算符出现在表达式的操作数之间,则表达式称为中缀表达式。简单的形式(operand1 运算符 )。
示例 : (A+B) * (CD)
前缀:如果运算符出现在表达式中的操作数之前,则表达式称为前缀表达式。简单的形式(运算符 )。
示例: *+AB-CD(中缀:(A+B) * (CD))
给定一个中缀表达式,使用两个堆栈将其转换为前缀表达式。
例子:
Input : A * B + C / D
Output : + * A B/ C D
Input : (A - B/C) * (A/K-L)
Output : *-A/BC-/AKL
推荐:请先在 IDE 上尝试您的方法,然后查看解决方案。
这个想法是使用一个堆栈来存储运算符,而另一个堆栈来存储操作数。逐步算法是:
- 遍历中缀表达式并检查给定字符是运算符还是操作数。
- 如果是操作数,则将其压入操作数堆栈。
- 如果是运算符,则检查当前运算符的优先级是否大于或小于或等于堆栈顶部的运算符。如果优先级更高,则将运算符符推入运算符堆栈。否则从操作数堆栈中弹出两个操作数,从运算符数堆栈中弹出运算符数并将字符串运算符数 + 操作数 2 + 操作数 1推入操作数堆栈。继续从两个堆栈中弹出并将结果压入操作数堆栈,直到当前运算符的优先级小于或等于运算符符堆栈顶部的运算符。
- 如果当前字符是'(',则将其压入运算符堆栈。
- 如果当前字符是')',则检查运算符堆栈的顶部是否是左括号。如果不从操作数堆栈中弹出两个操作数,则从运算符数堆栈中弹出运算符数并将字符串运算符数 + 操作数 2 + 操作数 1推入操作数堆栈。继续从两个堆栈中弹出并将结果推入操作数堆栈,直到运算符堆栈的顶部是一个左括号。
- 最终的前缀表达式出现在操作数堆栈的顶部。
下面是上述算法的实现:
C++
// CPP program to convert infix to prefix.
#include
using namespace std;
// Function to check if given character is
// an operator or not.
bool isOperator(char c)
{
return (!isalpha(c) && !isdigit(c));
}
// Function to find priority of given
// operator.
int getPriority(char C)
{
if (C == '-' || C == '+')
return 1;
else if (C == '*' || C == '/')
return 2;
else if (C == '^')
return 3;
return 0;
}
// Function that converts infix
// expression to prefix expression.
string infixToPrefix(string infix)
{
// stack for operators.
stack operators;
// stack for operands.
stack operands;
for (int i = 0; i < infix.length(); i++) {
// If current character is an
// opening bracket, then
// push into the operators stack.
if (infix[i] == '(') {
operators.push(infix[i]);
}
// If current character is a
// closing bracket, then pop from
// both stacks and push result
// in operands stack until
// matching opening bracket is
// not found.
else if (infix[i] == ')') {
while (!operators.empty() &&
operators.top() != '(') {
// operand 1
string op1 = operands.top();
operands.pop();
// operand 2
string op2 = operands.top();
operands.pop();
// operator
char op = operators.top();
operators.pop();
// Add operands and operator
// in form operator +
// operand1 + operand2.
string tmp = op + op2 + op1;
operands.push(tmp);
}
// Pop opening bracket from
// stack.
operators.pop();
}
// If current character is an
// operand then push it into
// operands stack.
else if (!isOperator(infix[i])) {
operands.push(string(1, infix[i]));
}
// If current character is an
// operator, then push it into
// operators stack after popping
// high priority operators from
// operators stack and pushing
// result in operands stack.
else {
while (!operators.empty() &&
getPriority(infix[i]) <=
getPriority(operators.top())) {
string op1 = operands.top();
operands.pop();
string op2 = operands.top();
operands.pop();
char op = operators.top();
operators.pop();
string tmp = op + op2 + op1;
operands.push(tmp);
}
operators.push(infix[i]);
}
}
// Pop operators from operators stack
// until it is empty and add result
// of each pop operation in
// operands stack.
while (!operators.empty()) {
string op1 = operands.top();
operands.pop();
string op2 = operands.top();
operands.pop();
char op = operators.top();
operators.pop();
string tmp = op + op2 + op1;
operands.push(tmp);
}
// Final prefix expression is
// present in operands stack.
return operands.top();
}
// Driver code
int main()
{
string s = "(A-B/C)*(A/K-L)";
cout << infixToPrefix(s);
return 0;
}
Java
// Java program to convert
// infix to prefix.
import java.util.*;
class GFG
{
// Function to check if
// given character is
// an operator or not.
static boolean isOperator(char c)
{
return (!(c >= 'a' && c <= 'z') &&
!(c >= '0' && c <= '9') &&
!(c >= 'A' && c <= 'Z'));
}
// Function to find priority
// of given operator.
static int getPriority(char C)
{
if (C == '-' || C == '+')
return 1;
else if (C == '*' || C == '/')
return 2;
else if (C == '^')
return 3;
return 0;
}
// Function that converts infix
// expression to prefix expression.
static String infixToPrefix(String infix)
{
// stack for operators.
Stack operators = new Stack();
// stack for operands.
Stack operands = new Stack();
for (int i = 0; i < infix.length(); i++)
{
// If current character is an
// opening bracket, then
// push into the operators stack.
if (infix.charAt(i) == '(')
{
operators.push(infix.charAt(i));
}
// If current character is a
// closing bracket, then pop from
// both stacks and push result
// in operands stack until
// matching opening bracket is
// not found.
else if (infix.charAt(i) == ')')
{
while (!operators.empty() &&
operators.peek() != '(')
{
// operand 1
String op1 = operands.peek();
operands.pop();
// operand 2
String op2 = operands.peek();
operands.pop();
// operator
char op = operators.peek();
operators.pop();
// Add operands and operator
// in form operator +
// operand1 + operand2.
String tmp = op + op2 + op1;
operands.push(tmp);
}
// Pop opening bracket
// from stack.
operators.pop();
}
// If current character is an
// operand then push it into
// operands stack.
else if (!isOperator(infix.charAt(i)))
{
operands.push(infix.charAt(i) + "");
}
// If current character is an
// operator, then push it into
// operators stack after popping
// high priority operators from
// operators stack and pushing
// result in operands stack.
else
{
while (!operators.empty() &&
getPriority(infix.charAt(i)) <=
getPriority(operators.peek()))
{
String op1 = operands.peek();
operands.pop();
String op2 = operands.peek();
operands.pop();
char op = operators.peek();
operators.pop();
String tmp = op + op2 + op1;
operands.push(tmp);
}
operators.push(infix.charAt(i));
}
}
// Pop operators from operators
// stack until it is empty and
// operation in add result of
// each pop operands stack.
while (!operators.empty())
{
String op1 = operands.peek();
operands.pop();
String op2 = operands.peek();
operands.pop();
char op = operators.peek();
operators.pop();
String tmp = op + op2 + op1;
operands.push(tmp);
}
// Final prefix expression is
// present in operands stack.
return operands.peek();
}
// Driver code
public static void main(String args[])
{
String s = "(A-B/C)*(A/K-L)";
System.out.println( infixToPrefix(s));
}
}
// This code is contributed
// by Arnab Kundu
Python3
# Python3 program to convert infix to prefix.
# Function to check if
# given character is
# an operator or not.
def isOperator(c):
return (not (c >= 'a' and c <= 'z') and not(c >= '0' and c <= '9') and not(c >= 'A' and c <= 'Z'))
# Function to find priority
# of given operator.
def getPriority(C):
if (C == '-' or C == '+'):
return 1
elif (C == '*' or C == '/'):
return 2
elif (C == '^'):
return 3
return 0
# Function that converts infix
# expression to prefix expression.
def infixToPrefix(infix):
# stack for operators.
operators = []
# stack for operands.
operands = []
for i in range(len(infix)):
# If current character is an
# opening bracket, then
# push into the operators stack.
if (infix[i] == '('):
operators.append(infix[i])
# If current character is a
# closing bracket, then pop from
# both stacks and push result
# in operands stack until
# matching opening bracket is
# not found.
elif (infix[i] == ')'):
while (len(operators)!=0 and operators[-1] != '('):
# operand 1
op1 = operands[-1]
operands.pop()
# operand 2
op2 = operands[-1]
operands.pop()
# operator
op = operators[-1]
operators.pop()
# Add operands and operator
# in form operator +
# operand1 + operand2.
tmp = op + op2 + op1
operands.append(tmp)
# Pop opening bracket
# from stack.
operators.pop()
# If current character is an
# operand then push it into
# operands stack.
elif (not isOperator(infix[i])):
operands.append(infix[i] + "")
# If current character is an
# operator, then push it into
# operators stack after popping
# high priority operators from
# operators stack and pushing
# result in operands stack.
else:
while (len(operators)!=0 and getPriority(infix[i]) <= getPriority(operators[-1])):
op1 = operands[-1]
operands.pop()
op2 = operands[-1]
operands.pop()
op = operators[-1]
operators.pop()
tmp = op + op2 + op1
operands.append(tmp)
operators.append(infix[i])
# Pop operators from operators
# stack until it is empty and
# operation in add result of
# each pop operands stack.
while (len(operators)!=0):
op1 = operands[-1]
operands.pop()
op2 = operands[-1]
operands.pop()
op = operators[-1]
operators.pop()
tmp = op + op2 + op1
operands.append(tmp)
# Final prefix expression is
# present in operands stack.
return operands[-1]
s = "(A-B/C)*(A/K-L)"
print( infixToPrefix(s))
# This code is contributed by decode2207.
C#
// C# program to convert
// infix to prefix.
using System;
using System.Collections.Generic;
public class GFG
{
// Function to check if
// given character is
// an operator or not.
static bool isOperator(char c)
{
return (!(c >= 'a' && c <= 'z') &&
!(c >= '0' && c <= '9') &&
!(c >= 'A' && c <= 'Z'));
}
// Function to find priority
// of given operator.
static int getPriority(char C)
{
if (C == '-' || C == '+')
return 1;
else if (C == '*' || C == '/')
return 2;
else if (C == '^')
return 3;
return 0;
}
// Function that converts infix
// expression to prefix expression.
static String infixToPrefix(String infix)
{
// stack for operators.
Stack operators = new Stack();
// stack for operands.
Stack operands = new Stack();
for (int i = 0; i < infix.Length; i++)
{
// If current character is an
// opening bracket, then
// push into the operators stack.
if (infix[i] == '(')
{
operators.Push(infix[i]);
}
// If current character is a
// closing bracket, then pop from
// both stacks and push result
// in operands stack until
// matching opening bracket is
// not found.
else if (infix[i] == ')')
{
while (operators.Count!=0 &&
operators.Peek() != '(')
{
// operand 1
String op1 = operands.Peek();
operands.Pop();
// operand 2
String op2 = operands.Peek();
operands.Pop();
// operator
char op = operators.Peek();
operators.Pop();
// Add operands and operator
// in form operator +
// operand1 + operand2.
String tmp = op + op2 + op1;
operands.Push(tmp);
}
// Pop opening bracket
// from stack.
operators.Pop();
}
// If current character is an
// operand then push it into
// operands stack.
else if (!isOperator(infix[i]))
{
operands.Push(infix[i] + "");
}
// If current character is an
// operator, then push it into
// operators stack after popping
// high priority operators from
// operators stack and pushing
// result in operands stack.
else
{
while (operators.Count!=0 &&
getPriority(infix[i]) <=
getPriority(operators.Peek()))
{
String op1 = operands.Peek();
operands.Pop();
String op2 = operands.Peek();
operands.Pop();
char op = operators.Peek();
operators.Pop();
String tmp = op + op2 + op1;
operands.Push(tmp);
}
operators.Push(infix[i]);
}
}
// Pop operators from operators
// stack until it is empty and
// operation in add result of
// each pop operands stack.
while (operators.Count!=0)
{
String op1 = operands.Peek();
operands.Pop();
String op2 = operands.Peek();
operands.Pop();
char op = operators.Peek();
operators.Pop();
String tmp = op + op2 + op1;
operands.Push(tmp);
}
// Final prefix expression is
// present in operands stack.
return operands.Peek();
}
// Driver code
public static void Main()
{
String s = "(A-B/C)*(A/K-L)";
Console.WriteLine( infixToPrefix(s));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
*-A/BC-/AKL
时间复杂度: O(n)
辅助空间: O(n)