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:
Subhradeep Bera
2023-09-19 00:57:36 +05:30
committed by GitHub
parent a1844840fd
commit 26c2465328
13 changed files with 21 additions and 23 deletions

View 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("[(])");
}
}

View File

@ -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
*/

View File

@ -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();
}
}

View File

@ -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();
}
}

View 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;
}
}
}

View 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");
}
}

View 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);
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View 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)))");
}
}

View File

@ -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();
}
}