I've written a program that takes a mathematical formula as an user input and converts it from infix to postfix.
It doesn't support negative numbers.
The program doesn't depend on the user having to pay attention on how to use spaces, so '1+2*3' and '1 + 2 * 3' are the same. (formulas like 'x^2^3' however must be written like 'x^(2^3)')
It provides support for the following operators: +, -, *, /, ^
Originally I had written a stack class completely myself, but this one (credits for stack class go to users of that post) is much more useful/reusable so I updated mine.
import java.util.EmptyStackException;
public class MyStack<T> {
private T[] data;
private int numElements;
public MyStack(int capacity) {
data = newArray(capacity);
numElements = 0;
}
private final T[] newArray(int capacity) {
@SuppressWarnings("unchecked")
T[] tmp = (T[]) new Object[capacity];
return tmp;
}
private void enlarge() {
T[] temp = data;
data = newArray(temp.length * 2);
System.arraycopy(temp, 0, data, 0, temp.length);
}
public void push(T element) {
if (numElements == data.length) {
enlarge();
}
else {
data[numElements++] = element;
}
}
public T peek() {
if (isEmpty()) {
throw new EmptyStackException();
}
return data[numElements - 1];
}
public boolean isEmpty() {
return (numElements == 0);
}
public T pop() {
if (isEmpty()) {
throw new EmptyStackException();
}
return data[--numElements];
}
}
Here is the InfixToPostfix
class itself:
import java.util.Scanner;
public class InfixToPostfix {
//checks whether c is operator
private static boolean isOperator(char c) {
if (c == '+' || c == '-' || c == '*' || c == '/' ||
c == '^' || c == '(' || c == ')') {
return true;
}
else return false;
}
//compares precedence of topmost operator in stack with operator at current position in infix-string
private static boolean isLowerPrecedence(char operatorOldChar, char operatorNewChar) {
boolean check = true; //true = new operator has higher precedence than old operator; false = contrary
int operatorOld = 0, operatorNew = 0; //will compare precedence of operators; higher number = higher precedence
//assign precedence to old operator (topmost in stack)
if (operatorOldChar == '+' || operatorOldChar == '-') operatorOld = 2;
else if (operatorOldChar == '*' || operatorOldChar == '/') operatorOld = 3;
else if (operatorOldChar == '^') operatorOld = 4;
//assign precedence to new operator (current character in infix)
if (operatorNewChar == '+' || operatorNewChar == '-') operatorNew = 2;
else if (operatorNewChar == '*' || operatorNewChar == '/') operatorNew = 3;
else if (operatorNewChar == '^') operatorNew = 4;
if (operatorNewChar == '(') {
check = false;
}
else if (operatorNewChar == ')') {
check = true;
}
else if (operatorOld < operatorNew) {
check = false;
}
else if (operatorOld >= operatorNew) {
check = true;
}
return check;
}
public static String convertToPostfix(String infix) {
MyStack<Character> stack = new MyStack<>(infix.length());
StringBuilder postfix = new StringBuilder();
boolean isStillOneNumber = true; //will differentiate between outputs like 11 or 1 1
for (int i = 0; i < infix.length(); i++) {
if (!isOperator(infix.charAt(i)) & infix.charAt(i) != ' ') { //handles numbers and constants
if (isStillOneNumber) {
postfix.append(infix.charAt(i));
}
else {
postfix.append(" ");
postfix.append(infix.charAt(i));
}
isStillOneNumber = true;
}
else if (isOperator(infix.charAt(i))){ //handles operators
if (infix.charAt(i) == ')') {
while (!stack.isEmpty() & stack.peek() != '(') {
postfix.append(" ");
postfix.append(stack.pop());
}
if (!stack.isEmpty()) {
stack.pop();
}
}
else {
if (!stack.isEmpty()) {
if (!isLowerPrecedence(stack.peek(), infix.charAt(i))) {
stack.push(infix.charAt(i));
}
else {
while (!stack.isEmpty()) {
postfix.append(" ");
postfix.append(stack.pop());
}
stack.push(infix.charAt(i));
}
}
else if (stack.isEmpty()) {
stack.push(infix.charAt(i));
}
}
isStillOneNumber = false;
}
else { //handles possible spaces in infix
isStillOneNumber = false;
}
}
while (!stack.isEmpty()) {
postfix.append(" ");
postfix.append(stack.pop());
}
return postfix.toString();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter formula: ");
String infix = scanner.nextLine();
System.out.println(convertToPostfix(infix));
}
}
I'd love to hear your opinions on my code!