Repository: TheAlgorithms/Java
File: src/main/java/com/thealgorithms/stacks/InfixToPrefix.java (Java)

Code before:
package com.thealgorithms.stacks;

import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class InfixToPrefix {
    private InfixToPrefix() {
    }

    /**
     * Convert an infix expression to a prefix expression.
     *
     * @param infixExpression the infix expression to convert
     * @return the prefix expression
     * @throws IllegalArgumentException if the infix expression has unbalanced brackets
     * @throws NullPointerException     if the infix expression is null
     */
    public static String infix2Prefix(String infixExpression) throws IllegalArgumentException {
        // Check for unbalanced brackets
        if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
            throw new IllegalArgumentException("invalid expression");
        }
        // Null input
        if (infixExpression == null) {
            throw new NullPointerException("null input");
        }
        // Empty string
        if (infixExpression.isEmpty()) {
            return "";
        }
        StringBuilder output = new StringBuilder();
        Stack<Character> stack = new Stack<>();
        // Reverse the infix expression for prefix conversion
        String reversedInfix = new StringBuilder(infixExpression).reverse().toString();
        for (char element : reversedInfix.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());
                }

Review comment (suggestion):
And it would be better to carry out the following sequence of checks:

```
    if (infixExpression == null) {
        throw new NullPointerException("Input expression cannot be null.");
    }

    if (infixExpression.trim().isEmpty()) {
        return "";
    }

    if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
        throw new IllegalArgumentException("Invalid expression: unbalanced brackets.");
    }
```

Code after:
package com.thealgorithms.stacks;

import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class InfixToPrefix {
    private InfixToPrefix() {
    }

    /**
     * Convert an infix expression to a prefix expression using stack.
     *
     * @param infixExpression the infix expression to convert
     * @return the prefix expression
     * @throws IllegalArgumentException if the infix expression has unbalanced brackets
     * @throws NullPointerException     if the infix expression is null
     */
    public static String infix2Prefix(String infixExpression) throws IllegalArgumentException {
        if (infixExpression == null) {
            throw new NullPointerException("Input expression cannot be null.");
        }
        infixExpression = infixExpression.trim();
        if (infixExpression.isEmpty()) {
            return "";
        }
        if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) {
            throw new IllegalArgumentException("Invalid expression: unbalanced brackets.");
        }

        StringBuilder output = new StringBuilder();
        Stack<Character> stack = new Stack<>();
        // Reverse the infix expression for prefix conversion
        String reversedInfix = new StringBuilder(infixExpression).reverse().toString();
        for (char element : reversedInfix.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);