mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-23 20:44:39 +08:00
Moved StackPostfixNotation.java from the Others section to the Stack section (#4372)
* Moved StackPostfixNotation.java from the Others section to the Stack section * Put all stack related algo in a separate stack directory in the algorithms directory. The stack directory under data-structures now only contains various implementations of the stack data structure. * formatted files
This commit is contained in:
82
src/main/java/com/thealgorithms/stacks/BalancedBrackets.java
Normal file
82
src/main/java/com/thealgorithms/stacks/BalancedBrackets.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* The nested brackets problem is a problem that determines if a sequence of
|
||||
* brackets are properly nested. A sequence of brackets s is considered properly
|
||||
* nested if any of the following conditions are true: - s is empty - s has the
|
||||
* form (U) or [U] or {U} where U is a properly nested string - s has the form
|
||||
* VW where V and W are properly nested strings For example, the string
|
||||
* "()()[()]" is properly nested but "[(()]" is not. The function called
|
||||
* is_balanced takes as input a string S which is a sequence of brackets and
|
||||
* returns true if S is nested and false otherwise.
|
||||
*
|
||||
* @author akshay sharma
|
||||
* @author <a href="https://github.com/khalil2535">khalil2535<a>
|
||||
* @author shellhub
|
||||
*/
|
||||
class BalancedBrackets {
|
||||
|
||||
/**
|
||||
* Check if {@code leftBracket} and {@code rightBracket} is paired or not
|
||||
*
|
||||
* @param leftBracket left bracket
|
||||
* @param rightBracket right bracket
|
||||
* @return {@code true} if {@code leftBracket} and {@code rightBracket} is
|
||||
* paired, otherwise {@code false}
|
||||
*/
|
||||
public static boolean isPaired(char leftBracket, char rightBracket) {
|
||||
char[][] pairedBrackets = {
|
||||
{'(', ')'},
|
||||
{'[', ']'},
|
||||
{'{', '}'},
|
||||
{'<', '>'},
|
||||
};
|
||||
for (char[] pairedBracket : pairedBrackets) {
|
||||
if (pairedBracket[0] == leftBracket && pairedBracket[1] == rightBracket) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if {@code brackets} is balanced
|
||||
*
|
||||
* @param brackets the brackets
|
||||
* @return {@code true} if {@code brackets} is balanced, otherwise
|
||||
* {@code false}
|
||||
*/
|
||||
public static boolean isBalanced(String brackets) {
|
||||
if (brackets == null) {
|
||||
throw new IllegalArgumentException("brackets is null");
|
||||
}
|
||||
Stack<Character> bracketsStack = new Stack<>();
|
||||
for (char bracket : brackets.toCharArray()) {
|
||||
switch (bracket) {
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
bracketsStack.push(bracket);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if (bracketsStack.isEmpty() || !isPaired(bracketsStack.pop(), bracket)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other character is invalid */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return bracketsStack.isEmpty();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert isBalanced("[()]{}{[()()]()}");
|
||||
assert !isBalanced("[(])");
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Author : Siddhant Swarup Mallick
|
||||
* Github : https://github.com/siddhant2002
|
||||
*/
|
||||
|
||||
/**
|
||||
* Program description - Given an integer array. The task is to find the maximum of the minimum of
|
||||
* the array
|
||||
*/
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CalculateMaxOfMin {
|
||||
|
||||
public static int calculateMaxOfMin(int[] a) {
|
||||
int n = a.length;
|
||||
int[] ans = new int[n];
|
||||
int[] arr2 = Arrays.copyOf(a, n);
|
||||
Arrays.sort(arr2);
|
||||
int maxNum = arr2[arr2.length - 1];
|
||||
ans[0] = maxNum;
|
||||
int index = 1;
|
||||
while (index != ans.length) {
|
||||
int[] minimums = new int[n - index];
|
||||
for (int i = 0; i < n - index; i++) {
|
||||
int[] windowArray = Arrays.copyOfRange(a, i, i + index + 1);
|
||||
Arrays.sort(windowArray);
|
||||
int minNum = windowArray[0];
|
||||
minimums[i] = minNum;
|
||||
}
|
||||
Arrays.sort(minimums);
|
||||
ans[index] = minimums[minimums.length - 1];
|
||||
index += 1;
|
||||
}
|
||||
return ans[0];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an integer array. The task is to find the maximum of the minimum of the
|
||||
* given array
|
||||
*/
|
@ -0,0 +1,58 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class DecimalToAnyUsingStack {
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert convert(0, 2).equals("0");
|
||||
assert convert(30, 2).equals("11110");
|
||||
assert convert(30, 8).equals("36");
|
||||
assert convert(30, 10).equals("30");
|
||||
assert convert(30, 16).equals("1E");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal number to another radix
|
||||
*
|
||||
* @param number the number to be converted
|
||||
* @param radix the radix
|
||||
* @return another radix
|
||||
* @throws ArithmeticException if <tt>number</tt> or <tt>radius</tt> is
|
||||
* invalid
|
||||
*/
|
||||
private static String convert(int number, int radix) {
|
||||
if (radix < 2 || radix > 16) {
|
||||
throw new ArithmeticException(String.format("Invalid input -> number:%d,radius:%d", number, radix));
|
||||
}
|
||||
char[] tables = {
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
};
|
||||
Stack<Character> bits = new Stack<>();
|
||||
do {
|
||||
bits.push(tables[number % radix]);
|
||||
number = number / radix;
|
||||
} while (number != 0);
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
while (!bits.isEmpty()) {
|
||||
result.append(bits.pop());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
// 1. You are given a string exp representing an expression.
|
||||
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each
|
||||
// other.
|
||||
// 3. But, some of the pair of brackets maybe extra/needless.
|
||||
// 4. You are required to print true if you detect extra brackets and false otherwise.
|
||||
// e.g.'
|
||||
// ((a + b) + (c + d)) -> false
|
||||
// (a + b) + ((c + d)) -> true
|
||||
import java.util.*;
|
||||
|
||||
public class DuplicateBrackets {
|
||||
|
||||
public static boolean check(String str) {
|
||||
Stack<Character> st = new Stack<>();
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char ch = str.charAt(i);
|
||||
if (ch == ')') {
|
||||
if (st.peek() == '(') {
|
||||
return true;
|
||||
} else {
|
||||
while (st.size() > 0 && st.peek() != '(') {
|
||||
st.pop();
|
||||
}
|
||||
st.pop();
|
||||
}
|
||||
} else {
|
||||
st.push(ch);
|
||||
}
|
||||
// System.out.println(st);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
String str = sc.nextLine();
|
||||
System.out.println(check(str));
|
||||
sc.close();
|
||||
}
|
||||
}
|
56
src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
Normal file
56
src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class InfixToPostfix {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
assert "32+".equals(infix2PostFix("3+2"));
|
||||
assert "123++".equals(infix2PostFix("1+(2+3)"));
|
||||
assert "34+5*6-".equals(infix2PostFix("(3+4)*5-6"));
|
||||
}
|
||||
|
||||
public static String infix2PostFix(String infixExpression) throws Exception {
|
||||
if (!BalancedBrackets.isBalanced(infixExpression)) {
|
||||
throw new Exception("invalid expression");
|
||||
}
|
||||
StringBuilder output = new StringBuilder();
|
||||
Stack<Character> stack = new Stack<>();
|
||||
for (char element : infixExpression.toCharArray()) {
|
||||
if (Character.isLetterOrDigit(element)) {
|
||||
output.append(element);
|
||||
} else if (element == '(') {
|
||||
stack.push(element);
|
||||
} else if (element == ')') {
|
||||
while (!stack.isEmpty() && stack.peek() != '(') {
|
||||
output.append(stack.pop());
|
||||
}
|
||||
stack.pop();
|
||||
} else {
|
||||
while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) {
|
||||
output.append(stack.pop());
|
||||
}
|
||||
stack.push(element);
|
||||
}
|
||||
}
|
||||
while (!stack.isEmpty()) {
|
||||
output.append(stack.pop());
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private static int precedence(char operator) {
|
||||
switch (operator) {
|
||||
case '+':
|
||||
case '-':
|
||||
return 0;
|
||||
case '*':
|
||||
case '/':
|
||||
return 1;
|
||||
case '^':
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
35
src/main/java/com/thealgorithms/stacks/LargestRectangle.java
Normal file
35
src/main/java/com/thealgorithms/stacks/LargestRectangle.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author mohd rameez github.com/rameez471
|
||||
*/
|
||||
|
||||
public class LargestRectangle {
|
||||
|
||||
public static String largestRectanglehistogram(int[] heights) {
|
||||
int n = heights.length, maxArea = 0;
|
||||
Stack<int[]> st = new Stack<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
int start = i;
|
||||
while (!st.isEmpty() && st.peek()[1] > heights[i]) {
|
||||
int[] tmp = st.pop();
|
||||
maxArea = Math.max(maxArea, tmp[1] * (i - tmp[0]));
|
||||
start = tmp[0];
|
||||
}
|
||||
st.push(new int[] {start, heights[i]});
|
||||
}
|
||||
while (!st.isEmpty()) {
|
||||
int[] tmp = st.pop();
|
||||
maxArea = Math.max(maxArea, tmp[1] * (n - tmp[0]));
|
||||
}
|
||||
return Integer.toString(maxArea);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert largestRectanglehistogram(new int[] {2, 1, 5, 6, 2, 3}).equals("10");
|
||||
assert largestRectanglehistogram(new int[] {2, 4}).equals("4");
|
||||
}
|
||||
}
|
105
src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java
Normal file
105
src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java
Normal file
@ -0,0 +1,105 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Given an integer array. The task is to find the maximum of the minimum of
|
||||
* every window size in the array. Note: Window size varies from 1 to the size
|
||||
* of the Array.
|
||||
* <p>
|
||||
* For example,
|
||||
* <p>
|
||||
* N = 7
|
||||
* arr[] = {10,20,30,50,10,70,30}
|
||||
* <p>
|
||||
* So the answer for the above would be : 70 30 20 10 10 10 10
|
||||
* <p>
|
||||
* We need to consider window sizes from 1 to length of array in each iteration.
|
||||
* So in the iteration 1 the windows would be [10], [20], [30], [50], [10],
|
||||
* [70], [30]. Now we need to check the minimum value in each window. Since the
|
||||
* window size is 1 here the minimum element would be the number itself. Now the
|
||||
* maximum out of these is the result in iteration 1. In the second iteration we
|
||||
* need to consider window size 2, so there would be [10,20], [20,30], [30,50],
|
||||
* [50,10], [10,70], [70,30]. Now the minimum of each window size would be
|
||||
* [10,20,30,10,10] and the maximum out of these is 30. Similarly we solve for
|
||||
* other window sizes.
|
||||
*
|
||||
* @author sahil
|
||||
*/
|
||||
public class MaximumMinimumWindow {
|
||||
|
||||
/**
|
||||
* This function contains the logic of finding maximum of minimum for every
|
||||
* window size using Stack Data Structure.
|
||||
*
|
||||
* @param arr Array containing the numbers
|
||||
* @param n Length of the array
|
||||
* @return result array
|
||||
*/
|
||||
public static int[] calculateMaxOfMin(int[] arr, int n) {
|
||||
Stack<Integer> s = new Stack<>();
|
||||
int[] left = new int[n + 1];
|
||||
int[] right = new int[n + 1];
|
||||
for (int i = 0; i < n; i++) {
|
||||
left[i] = -1;
|
||||
right[i] = n;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
while (!s.empty() && arr[s.peek()] >= arr[i]) {
|
||||
s.pop();
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
left[i] = s.peek();
|
||||
}
|
||||
|
||||
s.push(i);
|
||||
}
|
||||
|
||||
while (!s.empty()) {
|
||||
s.pop();
|
||||
}
|
||||
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
while (!s.empty() && arr[s.peek()] >= arr[i]) {
|
||||
s.pop();
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
right[i] = s.peek();
|
||||
}
|
||||
|
||||
s.push(i);
|
||||
}
|
||||
|
||||
int[] ans = new int[n + 1];
|
||||
for (int i = 0; i <= n; i++) {
|
||||
ans[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int len = right[i] - left[i] - 1;
|
||||
|
||||
ans[len] = Math.max(ans[len], arr[i]);
|
||||
}
|
||||
|
||||
for (int i = n - 1; i >= 1; i--) {
|
||||
ans[i] = Math.max(ans[i], ans[i + 1]);
|
||||
}
|
||||
|
||||
// Print the result
|
||||
for (int i = 1; i <= n; i++) {
|
||||
System.out.print(ans[i] + " ");
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = new int[] {10, 20, 30, 50, 10, 70, 30};
|
||||
int[] target = new int[] {70, 30, 20, 10, 10, 10, 10};
|
||||
int[] res = calculateMaxOfMin(arr, arr.length);
|
||||
assert Arrays.equals(target, res);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
/*
|
||||
Given an array "input" you need to print the first grater element for each element.
|
||||
For a given element x of an array, the Next Grater element of that element is the
|
||||
first grater element to the right side of it. If no such element is present print -1.
|
||||
|
||||
Example
|
||||
input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
At i = 0
|
||||
Next Grater element between (1 to n) is 7
|
||||
At i = 1
|
||||
Next Grater element between (2 to n) is 8
|
||||
At i = 2
|
||||
Next Grater element between (3 to n) is 5
|
||||
At i = 3
|
||||
Next Grater element between (4 to n) is 6
|
||||
At i = 4
|
||||
Next Grater element between (5 to n) is 6
|
||||
At i = 5
|
||||
Next Grater element between (6 to n) is 8
|
||||
At i = 6
|
||||
Next Grater element between (6 to n) is -1
|
||||
|
||||
result : [7, 8, 5, 6, 6, 8, -1]
|
||||
|
||||
1. If the stack is empty Push an element in the stack.
|
||||
2. If the stack is not empty:
|
||||
a. compare the top element of the stack with next.
|
||||
b. If next is greater than the top element, Pop element from the stack.
|
||||
next is the next greater element for the popped element.
|
||||
c. Keep popping from the stack while the popped element is smaller
|
||||
than next. next becomes the next greater element for all such
|
||||
popped elements.
|
||||
d. Finally, push the next in the stack.
|
||||
|
||||
3. If elements are left in stack after completing while loop then their Next Grater element is
|
||||
-1.
|
||||
*/
|
||||
|
||||
public class NextGraterElement {
|
||||
|
||||
public static int[] findNextGreaterElements(int[] array) {
|
||||
if (array == null) {
|
||||
return array;
|
||||
}
|
||||
|
||||
int[] result = new int[array.length];
|
||||
Stack<Integer> stack = new Stack<>();
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
while (!stack.isEmpty() && array[stack.peek()] < array[i]) {
|
||||
result[stack.pop()] = array[i];
|
||||
}
|
||||
stack.push(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextGreaterElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
/*
|
||||
Given an array "input" you need to print the first smaller element for each element to the left
|
||||
side of an array. For a given element x of an array, the Next Smaller element of that element is
|
||||
the first smaller element to the left side of it. If no such element is present print -1.
|
||||
|
||||
Example
|
||||
input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
At i = 0
|
||||
No elements to left of it : -1
|
||||
At i = 1
|
||||
Next smaller element between (0 , 0) is 2
|
||||
At i = 2
|
||||
Next smaller element between (0 , 1) is 2
|
||||
At i = 3
|
||||
Next smaller element between (0 , 2) is 3
|
||||
At i = 4
|
||||
Next smaller element between (0 , 3) is 3
|
||||
At i = 5
|
||||
Next smaller element between (0 , 4) is 4
|
||||
At i = 6
|
||||
Next smaller element between (0 , 5) is 6
|
||||
|
||||
result : [-1, 2, 2, 3, 3, 4, 6]
|
||||
|
||||
1) Create a new empty stack st
|
||||
|
||||
2) Iterate over array "input" , where "i" goes from 0 to input.length -1.
|
||||
a) We are looking for value just smaller than `input[i]`. So keep popping from "stack"
|
||||
till elements in "stack.peek() >= input[i]" or stack becomes empty.
|
||||
b) If the stack is non-empty, then the top element is our previous element. Else the
|
||||
previous element does not exist. c) push input[i] in stack. 3) If elements are left then their
|
||||
answer is -1
|
||||
*/
|
||||
|
||||
public class NextSmallerElement {
|
||||
|
||||
public static int[] findNextSmallerElements(int[] array) {
|
||||
// base case
|
||||
if (array == null) {
|
||||
return array;
|
||||
}
|
||||
Stack<Integer> stack = new Stack<>();
|
||||
int[] result = new int[array.length];
|
||||
Arrays.fill(result, -1);
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
while (!stack.empty() && stack.peek() >= array[i]) stack.pop();
|
||||
if (stack.empty()) {
|
||||
result[i] = -1;
|
||||
} else {
|
||||
result[i] = stack.peek();
|
||||
}
|
||||
stack.push(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextSmallerElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
}
|
129
src/main/java/com/thealgorithms/stacks/PostfixToInfix.java
Normal file
129
src/main/java/com/thealgorithms/stacks/PostfixToInfix.java
Normal file
@ -0,0 +1,129 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Postfix to Infix implementation via Stack
|
||||
*
|
||||
* Function: String getPostfixToInfix(String postfix)
|
||||
* Returns the Infix Expression for the given postfix parameter.
|
||||
*
|
||||
* Avoid using parentheses/brackets/braces for the postfix string.
|
||||
* Postfix Expressions don't require these.
|
||||
*
|
||||
*
|
||||
* @author nikslyon19 (Nikhil Bisht)
|
||||
*
|
||||
*/
|
||||
|
||||
public class PostfixToInfix {
|
||||
|
||||
public static boolean isOperator(char token) {
|
||||
switch (token) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
case '^':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isValidPostfixExpression(String postfix) {
|
||||
/* Postfix expression length should NOT be less than 3 */
|
||||
if (postfix.length() < 3) return false;
|
||||
|
||||
/* First two characters should NOT be operators */
|
||||
if (isOperator(postfix.charAt(0))) return false;
|
||||
if (isOperator(postfix.charAt(1))) return false;
|
||||
|
||||
int operandCount = 0;
|
||||
int operatorCount = 0;
|
||||
|
||||
/* Traverse the postfix string to check if --> Number of operands = Number of operators + 1
|
||||
*/
|
||||
for (int i = 0; i < postfix.length(); i++) {
|
||||
char token = postfix.charAt(i);
|
||||
|
||||
if (isOperator(token)) {
|
||||
operatorCount++;
|
||||
if (operatorCount >= operandCount) return false;
|
||||
} else {
|
||||
if (operatorCount == 0) {
|
||||
operandCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (operandCount != operatorCount + 1) return false;
|
||||
|
||||
/* Operand count is set to 2 because:-
|
||||
*
|
||||
* 1) the previous set of operands & operators combined have become a single valid
|
||||
* expression, which could be considered/assigned as a single operand.
|
||||
*
|
||||
* 2) the operand in the current iteration.
|
||||
*/
|
||||
operandCount = 2;
|
||||
|
||||
/* Reset operator count */
|
||||
operatorCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (operandCount == operatorCount + 1);
|
||||
}
|
||||
|
||||
public static String getPostfixToInfix(String postfix) {
|
||||
String infix = "";
|
||||
|
||||
if (postfix.isEmpty()) return infix;
|
||||
|
||||
/* Validate Postfix expression before proceeding with the Infix conversion */
|
||||
if (!isValidPostfixExpression(postfix)) {
|
||||
throw new IllegalArgumentException("Invalid Postfix Expression");
|
||||
}
|
||||
|
||||
Stack<String> stack = new Stack<>();
|
||||
StringBuilder valueString = new StringBuilder();
|
||||
|
||||
String operandA, operandB;
|
||||
char operator;
|
||||
|
||||
for (int index = 0; index < postfix.length(); index++) {
|
||||
char token = postfix.charAt(index);
|
||||
|
||||
if (!isOperator(token)) {
|
||||
stack.push(Character.toString(token));
|
||||
continue;
|
||||
}
|
||||
|
||||
operator = token;
|
||||
operandB = stack.pop();
|
||||
operandA = stack.pop();
|
||||
|
||||
valueString.append('(');
|
||||
|
||||
valueString.append(operandA);
|
||||
valueString.append(operator);
|
||||
valueString.append(operandB);
|
||||
|
||||
valueString.append(')');
|
||||
|
||||
stack.push(valueString.toString());
|
||||
valueString.setLength(0);
|
||||
}
|
||||
|
||||
infix = stack.pop();
|
||||
return infix;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert getPostfixToInfix("ABC+/").equals("(A/(B+C))");
|
||||
assert getPostfixToInfix("AB+CD+*").equals("((A+B)*(C+D))");
|
||||
assert getPostfixToInfix("AB+C+D+").equals("(((A+B)+C)+D)");
|
||||
assert getPostfixToInfix("ABCDE^*/-").equals("(A-(B/(C*(D^E))))");
|
||||
assert getPostfixToInfix("AB+CD^/E*FGH+-^").equals("((((A+B)/(C^D))*E)^(F-(G+H)))");
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.thealgorithms.stacks;
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.Stack;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* @brief Utility class evaluating postix expressions, cf. https://en.wikipedia.org/wiki/Reverse_Polish_notation
|
||||
* @details The computation is done using Integers.
|
||||
*/
|
||||
public final class StackPostfixNotation {
|
||||
private StackPostfixNotation() {
|
||||
}
|
||||
|
||||
private static BiFunction<Integer, Integer, Integer> getOperator(final String operationSymbol) {
|
||||
// note the order of operands
|
||||
switch (operationSymbol) {
|
||||
case "+":
|
||||
return (a, b) -> b + a;
|
||||
case "-":
|
||||
return (a, b) -> b - a;
|
||||
case "*":
|
||||
return (a, b) -> b * a;
|
||||
case "/":
|
||||
return (a, b) -> b / a;
|
||||
default:
|
||||
throw new IllegalArgumentException("exp contains an unknown operation.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void performOperation(Stack<Integer> s, final String operationSymbol) {
|
||||
if (s.size() < 2) {
|
||||
throw new IllegalArgumentException("exp is not a proper postfix expression (too few arguments).");
|
||||
}
|
||||
s.push(getOperator(operationSymbol).apply(s.pop(), s.pop()));
|
||||
}
|
||||
|
||||
private static void consumeExpression(Stack<Integer> s, final String exp) {
|
||||
Scanner tokens = new Scanner(exp);
|
||||
|
||||
while (tokens.hasNext()) {
|
||||
if (tokens.hasNextInt()) {
|
||||
s.push(tokens.nextInt());
|
||||
} else {
|
||||
performOperation(s, tokens.next());
|
||||
}
|
||||
}
|
||||
tokens.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Evaluates the given postfix expression.
|
||||
* @param exp the expression to evaluate.
|
||||
* @return the value of the given expression.
|
||||
* @exception IllegalArgumentException exp is not a valid postix expression.
|
||||
*/
|
||||
public static int postfixEvaluate(final String exp) {
|
||||
Stack<Integer> s = new Stack<Integer>();
|
||||
consumeExpression(s, exp);
|
||||
if (s.size() != 1) {
|
||||
throw new IllegalArgumentException("exp is not a proper postfix expression.");
|
||||
}
|
||||
return s.pop();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user