How to properly evaluate postfix notations in java? - java

I've already made my code and it's working for some cases and isn't for other cases. It's hard to solve the level of precedence because of its complexity especially when it comes to relational and logical operators. I can already successfully convert infix to postfix notation but can't successfully evaluate the postfix.
import java.util.*;
import java.lang.Character;
public class PostEvaluator
{
private Stack stack;
private Queue queue;
public PostEvaluator()
{
stack = new Stack(256);
queue = new Queue();
}
//this function will check if the character being checked is an operator or not
private static boolean isOperator(String c)
{
if (!Character.isLetterOrDigit(c.charAt(0)))
return true;
else
return false;
}
//this function will calculate the necessary calculation needed
private int operate (int x, int y, String operator)
{
int result = 0;
switch (operator)
{
case "*":
result = x * y;
break;
case "/":
if (y != 0)
result = x / y;
else
{
System.out.println("Division by zero error!");
System.exit(0);
}
break;
case "+":
result = x + y;
break;
case "-":
result = x - y;
break;
case "%":
result = x % y;
break;
case "^":
result = x ^ y;
break;
case ">":
if (x > y)
return 1;
else
return 0;
case "<":
if (x < y)
return 1;
else
return 0;
case ">=":
if (x >= y)
return 1;
else
return 0;
case "<=":
if (x <= y)
return 1;
else
return 0;
case "!=":
if (x != y)
return 1;
else
return 0;
case "==":
if (x == y)
return 1;
else
return 0;
case "&&":
result = x & y;
break;
case "||":
result = x | y;
break;
}
return result;
}
private int notOperate (int x)
{
if (x == 0)
return 1;
else
return 0;
}
//this function will evaluate the post fix
public String evaluatePostFix(String input)
{
String val1, val2, result = "", temp;
int intVal1, intVal2;
Scanner kb = new Scanner(input);
//splits the input by operand
kb.useDelimiter(" ");
do
{
queue.enqueue(kb.next());
} while (kb.hasNext());
do
{
//assign the temp of the first data in the queue
temp = (String) queue.dequeue();
if (!(temp.equals("")))
{
//if the value is not an operator, push it to the stack
if (!isOperator(temp)) {
stack.push(temp);
}
else
{
if (!stack.isEmpty())
{
if (!(temp.equals("!")))
{
//assign the val 1 the last item in the stack to be evaluated
val1 = (String) stack.pop();
if (!stack.isEmpty()) {
val2 = (String) stack.pop();
intVal1 = Integer.parseInt(val1);
intVal2 = Integer.parseInt(val2);
result = Integer.toString(operate(intVal2, intVal1, temp));
stack.push(result);
}
else
{
System.out.println("Missing Operand/s Error");
System.exit(0);
}
}
else
{
val1 = (String) stack.pop();
intVal1 = Integer.parseInt(val1);
result = Integer.toString(notOperate (intVal1));
stack.push(result);
}
}
else
{
System.out.println("Missing Operand/s Error");
System.exit(0);
}
}
if (result.equals(""))
result = temp;
}
}while (!queue.isEmpty());
return result;
}
}
I've only seen postfix evaluation for arithmetic expressions without relational and logical operators

Related

Precedence of operators on RPN calculator power is not working

the result and everything was working for any input other than power(^) and modulo(%) operator can anyone tell me where my mistake is.
here is my Github link: https://github.com/mikiyas-ahmed/RPN/tree/master/RPN/src
if the input is 3*(2+3)-7+8*8 it works correctly
if the input is 8%2 or 2^3 it gives me an error
the postfix and calculator class is here
import java.util.ArrayList;
public class Calculator{
public double EvaluatePostfix(ArrayList<String> postfix) {
Stack result = new Stack();
for (int i = 0; i < postfix.size(); i++) {
String token=postfix.get(i);
if(tryParseInt(token)){
result.push(Double.parseDouble(token));
}
else {
double operand1=result.pop();
double operand2=result.pop();
System.out.println(operand2);
System.out.println(operand1);
System.out.println(token);
double calc= calculate(operand1, operand2, token);
System.out.println(calc);System.out.println();
result.push(calc);
}
}
return result.pop();
}
private static double calculate(double operand1, double operand2, String token) {
double result = 0.0;
switch (token)
{
case "+":
result= operand2 + operand1;
return result;
case "-":
result= operand2 - operand1;
return result;
case "/":
result= operand2 / operand1;
return result;
case "*":
result= operand2 * operand1;
return result;
case "%":
result=operand2 % operand1;
return result;
case "^":
result=operand1;
for(int i=1; i<= operand2; i++) {
result= result * operand1;}
return result;
}
return result;
}
public boolean tryParseInt(String s) {
try {
Double.parseDouble(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}
class Stack {
static final int MAX = 10;
int top;
double a[] = new double[MAX]; // Maximum size of Stack
boolean isEmpty()
{
return (top < 0);
}
Stack()
{
top = -1;
}
boolean push(double d){
if (top >= (MAX - 1)) {
System.out.println("Stack Overflow");
return false;
}
else {
a[++top] = d;
System.out.println(d + " pushed into stack");
return true;
}
}
double pop()
{
if (top < 0) {
System.out.println("Stack Underflow");
return 0;
}
else {
double x = a[top--];
return x;
}
}
double peek()
{
if (top < 0) {
System.out.println("Stack Underflow");
return 0;
}
else {
double x = a[top];
return x;
}
}
}
import java.util.ArrayList;
public class PostfixCreater {
private enum Precedence
{
lp(0), rp(1), add(2), minus(3), divide(4), mult(5), mod(6),pow(7), noth(8), number(9);
private int index;
Precedence(int index)
{
this.index = index;
}
public int getIndex()
{
return index;
}
}
/** in stack precedence **/
private static final int[] isp = {0, 19, 12, 12, 13, 13, 13, 14, 0};
/** incoming character precedence **/
private static final int[] icp = {20, 19, 12, 12, 13, 13, 13, 14, 0};
/** operators **/
private static final String[] operators = {"{", "}", "+", "-", "/", "*", "%", "^", " "};
public Precedence getToken(String symbol)
{
switch (symbol)
{
case "(" : return Precedence.lp;
case ")" : return Precedence.rp;
case "+" : return Precedence.add;
case "-" : return Precedence.minus;
case "/" : return Precedence.divide;
case "*" : return Precedence.mult;
case "%" : return Precedence.mod;
case "^" : return Precedence.pow;
case " " : return Precedence.noth;
default : return Precedence.number;
}
}
public boolean tryParseInt(String s) {
try {
Double.parseDouble(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public ArrayList<String> postfix(String infix)
{
ArrayList<String> postfix =new ArrayList<String>();
String[] t = infix.split("(?<=[-+*/()])|(?=[-+*/()])");
Stack stack = new Stack();
Precedence pretoken;
for (int i = 0; i < t.length; i++)
{
String token =t[i];
pretoken=getToken(t[i]);
/** if token is operand append to postfix **/
if (tryParseInt(token)){
postfix.add(t[i]);
}
/** if token is right parenthesis pop till matching left parenthesis **/
else if(pretoken==Precedence.rp) {
while (stack.peek() != Precedence.lp)
postfix.add(operators[stack.pop().getIndex()]);
/** discard left parenthesis **/
stack.pop();
}
else {
System.out.print(pretoken.getIndex());
System.out.println();
while (!stack.isEmpty() && isp[stack.peek().getIndex()] >= icp[pretoken.getIndex()])
{
postfix.add(operators[stack.pop().getIndex()]);
}
stack.push(pretoken);
}
}
while(!stack.isEmpty())
postfix.add(operators[stack.pop().getIndex()]);
return postfix;
}
class Stack {
static final int MAX = 10;
int top;
Precedence a[] = new Precedence[MAX]; // Maximum size of Stack
boolean isEmpty()
{
return (top < 0);
}
Stack()
{
top = -1;
}
boolean push(Precedence x)
{
if (top >= (MAX - 1)) {
System.out.println("Stack Overflow");
return false;
}
else {
a[++top] = x;
System.out.println(x + " pushed into stack");
return true;
}
}
Precedence pop()
{
// if (top < 0) {
// System.out.println("Stack Underflow");
// return 0;
// }
// else {
Precedence x = a[top--];
return x;
// }
}
Precedence peek()
{
// if (top < 0) {
// System.out.println("Stack Underflow");
// return 0;
// }
// else {
Precedence x = a[top];
return x;
// }
}
}
}

Conversion of an infix operation to a postfix operation

The code takes in an infix operation and converts it to a postfix operation. I have been able to to the conversion. The problem I'm facing is the spacing between operators. Also, I'd like to know how the postfix operation can be evaluated.
import java.io.IOException;
public class InToPost {
private Stack theStack;
private String input;
private String output = "";
public InToPost(String in) {
input = in;
int stackSize = input.length();
theStack = new Stack(stackSize);
}
public String doTrans() {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
gotOper(ch, 1);
break;
case '*':
case '/':
case '%':
gotOper(ch, 2);
break;
case '(':
theStack.push(ch);
break;
case ')':
gotParen(ch);
break;
default:
output = output + ch;
break;
}
}
while (!theStack.isEmpty()) {
output = output + theStack.pop();
}
System.out.println(output);
return output;
}
public void gotOper(char opThis, int prec1) {
while (!theStack.isEmpty()) {
char opTop = theStack.pop();
if (opTop == '(') {
theStack.push(opTop);
break;
}
else {
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < prec1) {
theStack.push(opTop);
break;
}
else
output = output + opTop;
}
}
theStack.push(opThis);
}
public void gotParen(char ch){
while (!theStack.isEmpty()) {
char chx = theStack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
public static void main(String[] args)
throws IOException {
String input = "13 + 23 - 42 * 2";
String output;
InToPost theTrans = new InToPost(input);
output = theTrans.doTrans();
System.out.println("Postfix is " + output + '\n');
}
class Stack {
private int maxSize;
private char[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j) {
stackArray[++top] = j;
}
public char pop() {
return stackArray[top--];
}
public char peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
The postfix output for this is:
13 23 + 42 2*-
whereas I am trying to get an output that looks like this:
13 23 + 42 2 * -
I am unable to space the operator in the output.

Unknown error in converting a multiple digit infix expression to postfix

The function code for converting infix to postfix expression, as follows
package swapnil.calcii;
import android.util.Log;
import java.util.Stack;
public class Calculate {
private static final String operators = "-+/*";
private static final String operands = "0123456789";
public int evalInfix(String infix) {
return evaluatePostfix(convert2Postfix(infix));
}
public String convert2Postfix(String infixExpr) {
char[] chars = infixExpr.toCharArray();
Stack<String> stack = new Stack<String>();
StringBuilder out = new StringBuilder(infixExpr.length());
for (char c : chars) {
if (isOperator(c)) {
while (!stack.isEmpty() && !stack.peek().equals("(")) {
if (operatorGreaterOrEqual(stack.peek(), c)) {
out.append(stack.pop());
} else {
break;
}
}
String s = ""+c;
stack.push(s);
}
else if (c == '(') {
String s = ""+c;
stack.push(s);
} else if (c == ')') {
while (!stack.isEmpty() && !stack.peek().equals("(")) {
out.append(stack.pop());
}
if (!stack.isEmpty()) {
stack.pop();
}
} else if (isOperand(c)) {
try{
StringBuilder num = new StringBuilder();
while(isOperand(stack.peek().charAt(0))) {
num.append(stack.pop());
out.append(num);
}
} catch (Exception e) {
Log.d("errrr", "error in inserting " + e.getMessage());
out.append(c);
}
out.append(c);
}
}
while (!stack.empty()) {
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr) {
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars) {
if (isOperand(c)) {
stack.push(c - '0'); // convert char to int val
} else if (isOperator(c)) {
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator) {
int ret = 0;
if (operator == '-' || operator == '+') {
ret = 1;
} else if (operator == '*' || operator == '/') {
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(String op1, char op2) {
char op = op1.charAt(0);
return getPrecedence(op) >= getPrecedence(op2);
}
private boolean isOperator(char val) {
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val) {
return operands.indexOf(val) >= 0;
}
}
crashes with unknown error.
I've written it myself and I can't figure out where I am going wrong.
Function works fine, if pushing one char when checking isOperand(c)
But using StringBuilder to push a multiple digit number crashes the code.
Help

Java print certain characters from an array

I have a string array that looks like this:
[67, +, 12, -, 45]
I want to print it out so that it looks like this:
67 12 + 45 -
Here's the code I'm trying to use to do this.
String[] temp = line.split(" ");
String tmp = line.replaceAll("\\s+","");
for(int i = 0; i < temp.length; i++)
{
if(isInt(temp[i]) == false)
{
expression = temp[i];
firstExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == false)
{
System.out.print(expression);
secondExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == true)
{
System.out.print(expression);
firstExp = false;
secondExp = false;
}
else
{
System.out.print(temp[i]);
}
}
firstExp and secondExp are Booleans that check for the expressions that should appear in the array. isInt() is just a method used to determine if the string is a number. Right now, all this code does is output this:
671245
public static void main (String[] args) throws java.lang.Exception
{
String[] expr = new String[]{"67", "+", "45", "-", "12", "*", "5", "/", "78"};
int current = 0;
StringBuilder postfix = new StringBuilder();
// handle first three
postfix.append(expr[current]).append(" ");
postfix.append(expr[current+2]).append(" ");
postfix.append(expr[current+1]).append(" ");
current += 3;
// handle rest
while( current <= expr.length-2 ){
postfix.append(expr[current+1]).append(" ");
postfix.append(expr[current]).append(" ");
current += 2;
}
System.out.println(postfix.toString());
}
Outputs:
67 45 + 12 - 5 * 78 /
You can run/edit this at: http://ideone.com/zcdlEq
I guess what you are trying to do is converting infix expression to post fix. Some time back I had written the following code:
public class InfixToPostfix {
private Stack stack;
private String input;
private String output = "";
public InfixToPostfix(String in) {
input = in;
int stackSize = input.length();
stack = new Stack(stackSize);
}
public String translate() {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
hastOperator(ch, 1);
break;
case '*':
case '/':
hastOperator(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
hasSuperior(ch);
break;
default:
output = output + ch;
break;
}
}
while (!stack.isEmpty()) {
output = output + stack.pop();
}
System.out.println(output);
return output;
}
public void hastOperator(char op, int precedence) {
while (!stack.isEmpty()) {
char opTop = stack.pop();
if (opTop == '(') {
stack.push(opTop);
break;
}
else {
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < precedence) {
stack.push(opTop);
break;
}
else
output = output + opTop;
}
}
stack.push(op);
}
public void hasSuperior(char ch){
while (!stack.isEmpty()) {
char chx = stack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
public static void main(String[] args)
throws IOException {
String input = "67 + 12 - 45";
String output;
InfixToPostfix theTrans = new InfixToPostfix(input);
output = theTrans.translate();
System.out.println("Postfix is " + output + '\n');
}
class Stack {
private int maxSize;
private char[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j) {
stackArray[++top] = j;
}
public char pop() {
return stackArray[top--];
}
public char peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
You may need to modify this program to read from an array, but that is very trivial.
Here's how you do it in one line:
System.out.println(Arrays.toString(temp).replaceAll("[^\\d +*/-]", "").replaceAll("[+*/-]) (\\d+)", "$2 $1"));

NullPointerException infix to postfix java using stack [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Currently I am working on a project using an ArrayStack to change an infix to postfix and evaluating the postfix evaluation. For the first operator that appears when the program reads it, it sends back
java.lang.NullPointerException
at InfixToPostfix.convertString(InfixToPostfix.java:27)
at Postfix.main(Postfix.java:20)
I debugged the program and I know it will have to deal with my push method in ArrayStack. I just don't know how to get rid of NullPointerException.
Here is my ArrayStack class.
import java.util.*;
public class ArrayStack<T> implements StackADT<T>{
private int top = 0;
private static final int DEFAULT_CAPACITY = 70;
private T[] stack;
#SuppressWarnings("unchecked")
public ArrayStack()
{
top = 0;
stack = (T[])(new Object[DEFAULT_CAPACITY]);
}
#SuppressWarnings("unchecked")
public ArrayStack (int initialCapacity)
{
top = 0;
stack = (T[])(new Object[initialCapacity]);
}
public boolean isEmpty()
{
if(top==0)
return true;
else
return false;
}
public T pop() throws StackIsEmptyException
{
T retVal;
if(isEmpty())
throw new StackIsEmptyException("Stack is Empty");
else{
top--;
retVal = stack[top];
}
return retVal;
}
**public void push (T element)
{
if (size() == stack.length)
expandCapacity();
top++;
element = stack[top];
}**
public T peek() throws StackIsEmptyException
{
if (isEmpty())
throw new StackIsEmptyException("Stack is Empty");
return stack[top-1];
}
#SuppressWarnings("unchecked")
private void expandCapacity()
{
T[] larger = (T[])(new Object[stack.length*2]);
for (int index=0; index < stack.length; index++)
larger[index] = stack[index];
stack = larger;
}
#Override
public String toString() {
String result = "";
for (int scan=0; scan < top; scan++)
result = result + stack[scan].toString() + "\n";
return result;
}
#Override
public int size() {
return top;
}
}
InfixToPostfix classe
public class InfixToPostfix {
private ArrayStack<Character> stack;
private String infix;
private String postfix= "";
public InfixToPostfix(String in, ArrayStack<Character> stack) {
infix = in;
this.stack = stack;
}
#SuppressWarnings("unused")
public String convertString (){
for (int i = 0; i< infix.length(); i++){
try {
char curChar = infix.charAt(i);
if(!isOperator(curChar)){
postfix = postfix + curChar;
if (i == (infix.length()-1)){
while(!stack.isEmpty()){
postfix += stack.pop();
}
}
}**else if(stack.isEmpty()&& isOperator(curChar)){
stack.push(curChar);**
}
else if(charPrec(curChar) == 4){
while (!stack.isEmpty() && stack.size() != '('){
postfix += stack.pop();
}
stack.pop();
}else if(!(stack.isEmpty())&&(precident(curChar,stack.peek()))){
stack.push(curChar);
if(charPrec(stack.peek())==3)
stack.push(curChar);
while (!(stack.isEmpty())&&(!precident(curChar,stack.peek()))){
postfix += stack.pop();
}
stack.push(curChar);
}
}
catch (StackIsEmptyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return postfix;
}
/**
* Evaluates the specified postfix expression. If an operand is
* encountered, it is pushed onto the stack. If an operator is
* encountered, two operands are popped, the operation is
* evaluated, and the result is pushed onto the stack.
* #param expr String representation of a postfix expression
* #return int value of the given expression
*/
public int evaluate (String expr)
{
int op1, op2, result = 0;
String token;
StringTokenizer tokenizer = new StringTokenizer (expr);
/* while (tokenizer.hasMoreTokens())
{
token = tokenizer.nextToken();
if (isOperator(token))
{
op2 = (stack.pop()).charValue();
op1 = (stack.pop()).charValue();
result = evalSingleOp (token.charAt(0), op1, op2);
stack.push (new Integer(result));
}
else
stack.push (new Integer(Integer.parseInt(token)));
} */
return result;
}
/**
* Determines if the specified token is an operator.
* #param token String representing a single token
* #return boolean true if token is operator
*/
private boolean isOperator (String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/") );
}
/**
* Performs integer evaluation on a single expression consisting of
* the specified operator and operands.
* #param operation operation to be performed
* #param op1 the first operand
* #param op2 the second operand
* #return int value of the expression
*/
private int evalSingleOp (char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case '+':
result = op1 + op2;
break;
case '-':
result = op1 - op2;
break;
case '*':
result = op1 * op2;
break;
case '/':
result = op1 / op2;
}
return result;
}
private boolean isOperator(char ch) {
if(ch=='/'||ch=='*'||ch=='+'||ch=='-')
return true;
else
return false;
}
private boolean precident(char one, char two) {
if(charPrec(one) >= charPrec(two));
return true;
}
private int charPrec(char ch) {
switch(ch) {
case '-':
return 1;
case '+':
return 1;
case '*':
return 2;
case '/':
return 2;
case '(':
return 3;
case ')':
return 4;
}
return 0; }
}
There are a few problems in your code... heres the ones I see:
when did a size() method ever return a char value? size() is a really bad method name.
The whole ArrayStack<T> implements StackADT<T> class should probably be CharacterStack implments StackADT<Character> which would simplify a lot of things
This line which I believe is on line 27 (where your nullpointer is), has: stack.size() != '(' but that makes little or no sense..... although it won't throw a null-pointer.
you do not indicate which line has the problem - mark it in the actual code so we can see it, and not have to count the lines ourselves.
The code method and variable names make reading it very difficult. Fix up your naming conventions, edit, and retry.
My guess is that if you todied up the code you will find the problem yourself.

Categories