Given an infix expression, the task is to convert it into a prefix expression using two stacks.
An infix expression is one in which the operator appears between operands. The general structure is: (operand1 operator operand2).
Example: (A + B) * (C - D)
A prefix expression (also called Polish Notation) places the operator before the operands. The structure becomes: (operator operand1 operand2). Example: * + A B - C D (equivalent to infix: (A + B) * (C - D))
Examples:
Input: (A+B)*(C-D)
Output: *+AB-CD
Explanation: (A + B) becomes +AB, (C - D) becomes -CD, then combined with * -> *+AB-CDInput: A+(B*C)
Output: +A*BC
Explanation: B*C becomes *BC, then added to A -> +A*BCInput: (A+B)/(C+D)
Output: /+AB+CD
We have already discussed an infix to prefix approach that first reverses the given infix, then converts to postfix and then reverses the postfix to get the final result. Here we are going to discuss a two stack approach.
Approach:
The idea is to use one stack for operators and one for operands. The thought process is to simulate how expressions are evaluated, giving precedence to higher priority operators and handling parentheses carefully. When encountering an operator, we apply the top ones with greater or equal precedence before pushing the new one. Finally, we pop remaining operators and build the result by combining them with top operands in prefix order.
Steps to implement the above idea:
- Start by initializing two stacks: one stack (operands) to hold operand strings, and another (operators) to hold operator characters.
- Loop through each character of the given infix expression.
- If the character is an opening parenthesis '(', simply push it onto the operators stack to mark the beginning of a sub-expression.
- If it's a closing parenthesis ')', repeatedly pop from the operators stack, and for each operator, pop two operands, combine them into a prefix expression, and push it back into the operands stack until we encounter the matching '('.
- If the character is an operand (alphanumeric), convert it into a string and push it into the operands stack as it will be part of the final expression.
- If it's an operator, then check precedence: while the operator at the top of the stack has greater or equal precedence, pop that operator and build prefix using the top two operands.
- After the loop ends, apply all the remaining operators in the stack the same way by combining them with top two operands and pushing back the result until only one operand (the prefix expression) remains.
// C++ program to convert infix to prefix
// using two stacks
#include <bits/stdc++.h>
using namespace std;
// Check if character is an operator
bool isOperator(char ch) {
return (ch == '+' || ch == '-' ||
ch == '*' || ch == '/' || ch == '^');
}
// Get precedence of operators
int precedence(char ch) {
if (ch == '^') return 3;
if (ch == '*' || ch == '/') return 2;
if (ch == '+' || ch == '-') return 1;
return -1;
}
// Convert infix to prefix using two stacks
string convertToPrefix(string &infix) {
// Stack to store operands (like A, B, etc.)
stack<string> operands;
// Stack to store operators (like +, -, etc.)
stack<char> operators;
int n = infix.length();
for (int i = 0; i < n; i++) {
// Skip whitespace characters
if (infix[i] == ' ') {
continue;
}
// If current character is opening parenthesis
else if (infix[i] == '(') {
operators.push(infix[i]);
}
// If current character is closing parenthesis
else if (infix[i] == ')') {
// Solve entire bracket expression
while (!operators.empty() && operators.top() != '(') {
// Pop two operands and one operator
string op2 = operands.top(); operands.pop();
string op1 = operands.top(); operands.pop();
char op = operators.top(); operators.pop();
// Form partial prefix expression
string expr = op + op1 + op2;
operands.push(expr);
}
// Pop the opening parenthesis
operators.pop();
}
// If it's an operand (alphanumeric character)
else if (isalnum(infix[i])) {
operands.push(string(1, infix[i]));
}
// If it's an operator (+, -, *, /, ^)
else if (isOperator(infix[i])) {
// While operator stack is not empty and precedence of
// current operator is less than or equal to top of stack
while (!operators.empty() &&
precedence(infix[i]) <= precedence(operators.top())) {
// Pop top two operands and one operator
string op2 = operands.top(); operands.pop();
string op1 = operands.top(); operands.pop();
char op = operators.top(); operators.pop();
// Form intermediate prefix expression
string expr = op + op1 + op2;
operands.push(expr);
}
// Push current operator onto operator stack
operators.push(infix[i]);
}
}
// Apply remaining operators in stack
while (!operators.empty()) {
// Pop two operands and one operator
string op2 = operands.top(); operands.pop();
string op1 = operands.top(); operands.pop();
char op = operators.top(); operators.pop();
// Form final prefix expression
string expr = op + op1 + op2;
operands.push(expr);
}
// Final expression at the top of operand stack
return operands.top();
}
// Driver code
int main() {
string s = "(A+B)*(C-D)";
cout << convertToPrefix(s) << endl;
return 0;
}
// Java program to convert infix to prefix
// using two stacks
import java.util.*;
class GfG {
// Check if character is an operator
static boolean isOperator(char ch) {
return (ch == '+' || ch == '-' ||
ch == '*' || ch == '/' || ch == '^');
}
// Get precedence of operators
static int precedence(char ch) {
if (ch == '^') return 3;
if (ch == '*' || ch == '/') return 2;
if (ch == '+' || ch == '-') return 1;
return -1;
}
// Convert infix to prefix using two stacks
static String convertToPrefix(String infix) {
// Stack to store operands (like A, B, etc.)
Stack<String> operands = new Stack<>();
// Stack to store operators (like +, -, etc.)
Stack<Character> operators = new Stack<>();
int n = infix.length();
for (int i = 0; i < n; i++) {
// Skip whitespace characters
if (infix.charAt(i) == ' ') {
continue;
}
// If current character is opening parenthesis
else if (infix.charAt(i) == '(') {
operators.push(infix.charAt(i));
}
// If current character is closing parenthesis
else if (infix.charAt(i) == ')') {
// Solve entire bracket expression
while (!operators.isEmpty() && operators.peek() != '(') {
// Pop two operands and one operator
String op2 = operands.pop();
String op1 = operands.pop();
char op = operators.pop();
// Form partial prefix expression
String expr = op + op1 + op2;
operands.push(expr);
}
// Pop the opening parenthesis
operators.pop();
}
// If it's an operand (alphanumeric character)
else if (Character.isLetterOrDigit(infix.charAt(i))) {
operands.push(String.valueOf(infix.charAt(i)));
}
// If it's an operator (+, -, *, /, ^)
else if (isOperator(infix.charAt(i))) {
// While operator stack is not empty and precedence of
// current operator is less than or equal to top of stack
while (!operators.isEmpty() &&
precedence(infix.charAt(i)) <= precedence(operators.peek())) {
// Pop top two operands and one operator
String op2 = operands.pop();
String op1 = operands.pop();
char op = operators.pop();
// Form intermediate prefix expression
String expr = op + op1 + op2;
operands.push(expr);
}
// Push current operator onto operator stack
operators.push(infix.charAt(i));
}
}
// Apply remaining operators in stack
while (!operators.isEmpty()) {
// Pop two operands and one operator
String op2 = operands.pop();
String op1 = operands.pop();
char op = operators.pop();
// Form final prefix expression
String expr = op + op1 + op2;
operands.push(expr);
}
// Final expression at the top of operand stack
return operands.peek();
}
public static void main(String[] args) {
String s = "(A+B)*(C-D)";
// Convert and print prefix expression
System.out.println(convertToPrefix(s));
}
}
# Python program to convert infix to prefix
# using two stacks
def isOperator(ch):
return ch in ['+', '-', '*', '/', '^']
def precedence(ch):
if ch == '^':
return 3
if ch == '*' or ch == '/':
return 2
if ch == '+' or ch == '-':
return 1
return -1
def convertToPrefix(infix):
# Stack to store operands (like A, B, etc.)
operands = []
# Stack to store operators (like +, -, etc.)
operators = []
n = len(infix)
for i in range(n):
# Skip whitespace characters
if infix[i] == ' ':
continue
# If current character is opening parenthesis
elif infix[i] == '(':
operators.append(infix[i])
# If current character is closing parenthesis
elif infix[i] == ')':
# Solve entire bracket expression
while operators and operators[-1] != '(':
# Pop two operands and one operator
op2 = operands.pop()
op1 = operands.pop()
op = operators.pop()
# Form partial prefix expression
expr = op + op1 + op2
operands.append(expr)
# Pop the opening parenthesis
operators.pop()
# If it's an operand (alphanumeric character)
elif infix[i].isalnum():
operands.append(infix[i])
# If it's an operator (+, -, *, /, ^)
elif isOperator(infix[i]):
# While operator stack is not empty and precedence of
# current operator is less than or equal to top of stack
while (operators and
precedence(infix[i]) <= precedence(operators[-1])):
# Pop top two operands and one operator
op2 = operands.pop()
op1 = operands.pop()
op = operators.pop()
# Form intermediate prefix expression
expr = op + op1 + op2
operands.append(expr)
# Push current operator onto operator stack
operators.append(infix[i])
# Apply remaining operators in stack
while operators:
# Pop two operands and one operator
op2 = operands.pop()
op1 = operands.pop()
op = operators.pop()
# Form final prefix expression
expr = op + op1 + op2
operands.append(expr)
# Final expression at the top of operand stack
return operands[-1]
if __name__ == "__main__":
s = "(A+B)*(C-D)"
# Convert and print prefix expression
print(convertToPrefix(s))
// C# program to convert infix to prefix
// using two stacks
using System;
using System.Collections.Generic;
class GfG {
// Check if character is an operator
static bool isOperator(char ch) {
return (ch == '+' || ch == '-' ||
ch == '*' || ch == '/' || ch == '^');
}
// Get precedence of operators
static int precedence(char ch) {
if (ch == '^') return 3;
if (ch == '*' || ch == '/') return 2;
if (ch == '+' || ch == '-') return 1;
return -1;
}
// Convert infix to prefix using two stacks
static string convertToPrefix(string infix) {
// Stack to store operands (like A, B, etc.)
Stack<string> operands = new Stack<string>();
// Stack to store operators (like +, -, etc.)
Stack<char> operators = new Stack<char>();
int n = infix.Length;
for (int i = 0; i < n; i++) {
// Skip whitespace characters
if (infix[i] == ' ') {
continue;
}
// If current character is opening parenthesis
else if (infix[i] == '(') {
operators.Push(infix[i]);
}
// If current character is closing parenthesis
else if (infix[i] == ')') {
// Solve entire bracket expression
while (operators.Count > 0 && operators.Peek() != '(') {
// Pop two operands and one operator
string op2 = operands.Pop();
string op1 = operands.Pop();
char op = operators.Pop();
// Form partial prefix expression
string expr = op + op1 + op2;
operands.Push(expr);
}
// Pop the opening parenthesis
operators.Pop();
}
// If it's an operand (alphanumeric character)
else if (Char.IsLetterOrDigit(infix[i])) {
operands.Push(infix[i].ToString());
}
// If it's an operator (+, -, *, /, ^)
else if (isOperator(infix[i])) {
// While operator stack is not empty and precedence of
// current operator is less than or equal to top of stack
while (operators.Count > 0 &&
precedence(infix[i]) <= precedence(operators.Peek())) {
// Pop top two operands and one operator
string op2 = operands.Pop();
string op1 = operands.Pop();
char op = operators.Pop();
// Form intermediate prefix expression
string expr = op + op1 + op2;
operands.Push(expr);
}
// Push current operator onto operator stack
operators.Push(infix[i]);
}
}
// Apply remaining operators in stack
while (operators.Count > 0) {
// Pop two operands and one operator
string op2 = operands.Pop();
string op1 = operands.Pop();
char op = operators.Pop();
// Form final prefix expression
string expr = op + op1 + op2;
operands.Push(expr);
}
// Final expression at the top of operand stack
return operands.Peek();
}
static void Main() {
string s = "(A+B)*(C-D)";
// Convert and print prefix expression
Console.WriteLine(convertToPrefix(s));
}
}
// JavaScript program to convert infix to prefix
// using two stacks
function isOperator(ch) {
return ['+', '-', '*', '/', '^'].includes(ch);
}
function precedence(ch) {
if (ch === '^') return 3;
if (ch === '*' || ch === '/') return 2;
if (ch === '+' || ch === '-') return 1;
return -1;
}
function convertToPrefix(infix) {
// Stack to store operands (like A, B, etc.)
let operands = [];
// Stack to store operators (like +, -, etc.)
let operators = [];
let n = infix.length;
for (let i = 0; i < n; i++) {
// Skip whitespace characters
if (infix[i] === ' ') {
continue;
}
// If current character is opening parenthesis
else if (infix[i] === '(') {
operators.push(infix[i]);
}
// If current character is closing parenthesis
else if (infix[i] === ')') {
// Solve entire bracket expression
while (operators.length && operators[operators.length - 1] !== '(') {
// Pop two operands and one operator
let op2 = operands.pop();
let op1 = operands.pop();
let op = operators.pop();
// Form partial prefix expression
let expr = op + op1 + op2;
operands.push(expr);
}
// Pop the opening parenthesis
operators.pop();
}
// If it's an operand (alphanumeric character)
else if (/[a-z0-9]/i.test(infix[i])) {
operands.push(infix[i]);
}
// If it's an operator (+, -, *, /, ^)
else if (isOperator(infix[i])) {
// While operator stack is not empty and precedence of
// current operator is less than or equal to top of stack
while (operators.length &&
precedence(infix[i]) <= precedence(operators[operators.length - 1])) {
// Pop top two operands and one operator
let op2 = operands.pop();
let op1 = operands.pop();
let op = operators.pop();
// Form intermediate prefix expression
let expr = op + op1 + op2;
operands.push(expr);
}
// Push current operator onto operator stack
operators.push(infix[i]);
}
}
// Apply remaining operators in stack
while (operators.length) {
// Pop two operands and one operator
let op2 = operands.pop();
let op1 = operands.pop();
let op = operators.pop();
// Form final prefix expression
let expr = op + op1 + op2;
operands.push(expr);
}
// Final expression at the top of operand stack
return operands[operands.length - 1];
}
let s = "(A+B)*(C-D)";
// Convert and print prefix expression
console.log(convertToPrefix(s));
Output
*+AB-CD
Time Complexity: O(n), each character is processed at most once using stack operations.
Space Complexity: O(n), stacks for operators and operands store up to n characters total.