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.
Related
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;
// }
}
}
}
I am finishing up an expression tree program that takes in a postfix and gives the answer and the orginal equation back in infix form. I started working on about 6 months ago and had an issue I couldn't figure out. It works fine if the numbers are smaller than 9. For instance, 2 5 * 4 - prints out The infix: (2*5-4) 6.0 works fine. Something like 10 2 * prints out 20.0 but prints out The infix: (0*2) which isn't right. The big problem is that if a number is bigger than 9 it doesn't read that number in properly which messes up the conversion to infix. I am not sure how to fix this problem exactly. Below is my class and tester class:
import java.util.NoSuchElementException;
import java.util.Stack;
public class ExpressionTree
{
private final String postfix;
private TreeNode root;
/**
* Takes in a valid postfix expression and its used to construct the expression tree.
*/
public ExpressionTree(String postfix)
{
if (postfix == null) { throw new NullPointerException("The posfix should not be null"); }
if (postfix.length() == 0) { throw new IllegalArgumentException("The postfix should not be empty"); }
this.postfix = postfix;
}
private static class TreeNode
{
TreeNode left;
char ch;
TreeNode right;
TreeNode(TreeNode left, char ch, TreeNode right) {
this.left = left;
this.ch = ch;
this.right = right;
}
}
/**
* Checks to see if it is an Operator
*/
private boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
/**
* Constructs an expression tree, using the postfix expression
*/
public void createExpressionTree()
{
final Stack<TreeNode> nodes = new Stack<TreeNode>();
for (int i = 0; i < postfix.length(); i++)
{
char ch = postfix.charAt(i);
if (isOperator(ch))
{
TreeNode rightNode = nodes.pop();
TreeNode leftNode = nodes.pop();
nodes.push(new TreeNode(leftNode, ch, rightNode));
}
else if (!Character.isWhitespace(ch))
{
nodes.add(new TreeNode(null, ch, null));
}
}
root = nodes.pop();
}
/**
* Returns the infix expression
*
* #return the string of infix.
*/
public String infix()
{
if (root == null)
{
throw new NoSuchElementException("The root is empty, the tree has not yet been constructed.");
}
final StringBuilder infix = new StringBuilder();
inOrder(root, infix);
return infix.toString();
}
private void inOrder(TreeNode node, StringBuilder infix)
{
if (node != null) {
inOrder(node.left, infix);
infix.append(node.ch);
inOrder(node.right, infix);
}
}
public Double evaluate(String postfix)
{
Stack<Double> s = new Stack<Double>();
char[] chars = postfix.toCharArray();
int N = chars.length;
for(int i = 0; i < N; i++)
{
char ch = chars[i];
if(isOperator(ch))
{
switch(ch)
{
case '+': s.push(s.pop() + s.pop()); break;
case '*': s.push(s.pop() * s.pop()); break;
case '-': s.push(-s.pop() + s.pop()); break;
case '/': s.push(1 / s.pop() * s.pop()); break;
}
}
else if(Character.isDigit(ch))
{
s.push(0.0);
while (Character.isDigit(chars[i]))
s.push(10.0 * s.pop() + (chars[i++] - '0'));
}
}
return s.pop();
}
}
And the tester:
import java.util.Scanner;
public class ExpressionTester
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String line = null;
while(true)
{
System.out.println("");
String pf = sc.nextLine();
if (pf.isEmpty())
{
break;
}
ExpressionTree eT = new ExpressionTree(pf);
eT.createExpressionTree();
System.out.println("The infix: " + "(" + eT.infix() + ")" );
System.out.println(eT.evaluate(pf));
}
}
}
I am tasked with creating a postFixEvaluator in java and everytime i try to pop an operand using the evaluateTwoOperations method, my program ends and produces the below error. What is causing this? to my knowledge, I have everything typecasted to be a Complex and not a Integer.
"Couldn't run PostfixEvaluator! java.lang.ClassCastException: java.lang.Integer cannot be cast to Complex"
Start of my postFixEvaluator class
#author Cody
*/
import java.util.*;
import java.io.*;
import java.util.StringTokenizer;
public class PostfixEvaluator
{
private static final int STACK_SIZE = 100;
private Stack operand;
private String expression;
private ArrayList<Complex> answers;
public static Complex result;
public void run() throws IOException
{
ArrayList<Complex> a = new ArrayList<>();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
//BufferedReader stdin = new BufferedReader(new FileReader("Prog3_1.in"));
operand = new Stack(STACK_SIZE);
boolean eof = false;
while (!eof) //while not done
{
expression = stdin.readLine(); //read a line of expression
//operand.clear(); //clear the stack
if (expression == null) //if no input, end program
{
eof = true;
}
else
{
result = evaluate(expression); //evaluate expression
}
if (result != null) //if the answer is valid
{
System.out.println("\nvalue: " + result.toString());
answers.add(result);//add answer to arrayList
}
else
{
System.out.println("\nInvalid Expression");
}
}
//read the ArrayList and print the results
/*
if (real)
/
for (int i = 0; i < answers.size(); i++)
{
System.out.println(answers.get(i));
}
*/
System.out.println("Normal termination of"
+ "program 3");
}
public Complex evaluate(String expression)
{
boolean valid = true;
StringTokenizer st = new StringTokenizer(expression); //tokenize the expression
String token; //get individual results of readLine
while (valid && st.hasMoreTokens()) //while valid and their are tokens remaining
{
token = st.nextToken(); //get next token
System.out.println("token is: " + token);
if (isOperator(token)) //if token is operator
{
if (isConjugate(token))
{// if token is conjugate
Complex result1 = evaluateConjugate(token);
operand.push(result1);
}
else //evaluate the operator and push the result
{
Complex result1 = evaluateTwoOperations(token);
operand.push(result1);
}
}
else
{
int value = Integer.parseInt(token);
operand.push(value);
}
}
Complex answer = (Complex) operand.pop();
return answer;
}
private Complex evaluateTwoOperations(String op)
{
Complex resultant = null;
if ( operand.isEmpty() )
System.out.println("Invalid Expression!");
else
{
Complex op2 = (Complex) operand.pop();
Complex op1 = (Complex) operand.pop();
switch (op.charAt(0)) //if op == '+'...
{
case '+':
resultant = op1.plus(op2);
break;
case '-':
resultant = op1.minus(op2);
case '*':
resultant = op1.times(op2);
}
return resultant;
}
return null;
}
private boolean isOperator(String token)
{
return token.equals("+") || token.equals("-")
|| token.equals("*") || token.equals("~");
}
private boolean isConjugate(String token)
{
return token.equals("~");
}
private Complex evaluateConjugate(String op)
{
Complex resultant = null;
if (operand.isEmpty())
System.out.println("Invalid Expression!");
else
{
Complex op1 = (Complex) operand.pop();
switch (op.charAt(0)) //if op == '~'
{
case '~':
resultant = op1.conjugate();
}
return resultant;
}
return null;
}
/*
private void outputExpression(String expression)
{
for (int i = 1; i < answers.size(); i++)
{
System.out.println("Expression " + i + ": " + expression);
}
}
*/
}
Start of my Complex class
#author Cody
*/
public class Complex
{
private int realNumber;
private int imagNumber;
private final int checker = 0;
/**
default constructor creates the default complex number a+bi where a=b=0.
*/
public Complex()
{
realNumber = checker;
imagNumber = checker;
}
/**
parameterized constructor creates the complex number a+bi, where b=0.
*/
public Complex(int real)
{
realNumber = real;
imagNumber = checker;
}
/**
parameterized constructor creates the complex number a+bi where a and b are
integers.
*/
public Complex(int real, int imag)
{
realNumber = real;
imagNumber = imag;
}
/**
method returns a new Complex number that represents the sum
of two Complex numbers.
#param cp
#return new summed complex number
*/
public Complex plus(Complex cp)
{
return new Complex(realNumber + cp.realNumber, imagNumber + cp.imagNumber);
}
/**
method returns a new Complex that represents the difference
between two Complex numbers
#param cp
#return difference of two Complex numbers
*/
public Complex minus(Complex cp)
{
return new Complex(realNumber - cp.realNumber, imagNumber - cp.imagNumber);
}
/**
method returns a new Complex that represents the product of
two Complex numbers
#param cp
#return product of two complex numbers
*/
public Complex times(Complex cp)
{
return new Complex(realNumber * cp.realNumber - imagNumber * cp.imagNumber,
realNumber * cp.realNumber + imagNumber * cp.realNumber);
}
/**
method should return a new Complex that is the conjugate of a
Complex number
#param none
#return conjugate of complex number
*/
public Complex conjugate()
{
return new Complex(realNumber, -imagNumber);
}
/**
method returns true if two Complex numbers have the same
real and imaginary; return false otherwise.
#param obj
#return true if two complex numbers are equal, false otherwise
*/
public boolean equals(Object obj)
{
if (obj instanceof Complex)
{
Complex n = (Complex) obj;
return n.realNumber == realNumber && n.imagNumber == imagNumber;
}
return false;
}
/**
method returns a complex number as a String.
uses multiple if statements to check validity
#param none
#return complex number as a string
*/
public String toString()
{
if (imagNumber == checker)
{
return String.valueOf(realNumber);
}
if (realNumber == checker && imagNumber == checker)
{
return String.valueOf(checker);
}
if (realNumber == checker)
{
return imagNumber + "i";
}
if (realNumber != checker && imagNumber < checker)
{
return realNumber + " - " + -imagNumber + "i";
}
if (realNumber != checker && imagNumber > checker)
{
return realNumber + " + " + imagNumber + "i";
}
return "invalid";
}
}
Start of my Stack class
/**
performs all practical Stack operations
#author Cody
*/
public class Stack
{
private Object[] elements;
private int top;
/**
parameterized constructor creates array of Elements with size of size
initializes top to 0
#param size
*/
public Stack(int size)
{
elements = new Object[size];
top = 0;
}
/**
checks to see if the array is empty
#param none
#return true if array is empty, false otherwise.
*/
public boolean isEmpty()
{
return top == 0;
}
/**
checks to see if the array is full
#param none
#return true if array is full, false otherwise.
*/
public boolean isFull()
{
return top == elements.length;
}
/**
returns the item most recently added to the stack. if the array is empty,
returns null
#param none
#return last item added to stack, null if empty array
*/
public Object peek()
{
if (top == 0)
return null;
return elements[top - 1];
}
/**
returns and deletes element most recently added to the stack
#param none
#return element most recently added to stack
*/
public Object pop()
{
return elements[--top];
}
/**
adds item to stack and increments top
#param obj
*/
public void push(Object obj)
{
elements[top++] = obj;
}
/**
returns number of items in stack
#param none
#return number of items in stack
*/
public int size()
{
return elements.length;
}
/**
clears the stack by popping everything in it
#param none
*/
public void clear()
{
for (int i = 0; i < size(); i++)
elements[i] = pop();
}
}
In your evaluate method, you have this piece of code:
int value = Integer.parseInt(token);
operand.push(value);
But when you pop such values , you are converting it to (Complex) in your evaluateTwoOperations method. Hence, you are getting the ClassCastException.
You already have a constructor to help you convert your Integer to Complex class
You could use that.
public Complex(int real)
{
realNumber = real;
imagNumber = checker;
}
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
This is my class:
import java.io.*;
import java.util.*;
import java.lang.*;
import java.util.Scanner;
import java.util.List;
import java.util.Stack;
/**
*
* #author rtibbetts268
*/
public class InfixToPostfix
{
/**
* Operators in reverse order of precedence.
*/
private static final String operators = "_-+/*";
private static final String operands = "0123456789x";
public String xToValue(String postfixExpr, String x)
{
char[] chars = postfixExpr.toCharArray();
StringBuilder newPostfixExpr = new StringBuilder();
for (char c : chars)
{
if (c == 'x')
{
newPostfixExpr.append(x);
}
else
{
newPostfixExpr.append(c);
}
}
return newPostfixExpr.toString();
}
public String convert2Postfix(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder in = new StringBuilder(infixExpr.length());
for (int i : chars)
{
if (infixExpr.charAt(i) == '-')
{
if (isOperand(infixExpr.charAt(i+1)))
{
if (i != infixExpr.length())
{
if (isOperator(infixExpr.charAt(i-1)))
in.append('_');
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
chars = in.toString().toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder out = new StringBuilder(in.toString().length());
for (char c : chars)
{
if (isOperator(c))
{
while (!stack.isEmpty() && stack.peek() != '(')
{
if (operatorGreaterOrEqual(stack.peek(), c))
{
out.append(stack.pop());
}
else
{
break;
}
}
stack.push(c);
}
else if (c == '(')
{
stack.push(c);
}
else if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
out.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else if (isOperand(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 == '_')
{
ret = 0;
}
if (operator == '-' || operator == '+')
{
ret = 1;
}
else if (operator == '*' || operator == '/')
{
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(char op1, char op2)
{
return getPrecedence(op1) >= getPrecedence(op2);
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
}
In it I change infix expressions to postfix expressions with the method convert2Postfix()
There is a small section in it at the very beginning where I am rewriting the string input with all negative numbers having a '_' infront of them instead of a "-". It doesn't work.
ex: change -4 to _4
What do I need to do to make this work?
You have a number of errors here, here is the first one:
for (int i : chars)
chars is converted to the corresponding int. For example if chars contains one single character 'A':
char [] chars = new char[1];
chars[0] = 'A';
for(int i: chars){
System.out.println(i); //You will have a '65' here
}
What you really mean is probably:
for (int i=0;i<chars.length;++i)
This is also wrong:
if (isOperator(infixExpr.charAt(i-1)))
It should be :
if (isOperator(infixExpr.charAt(i)))
Then there is a problem in the way you put and remove elements in the stack.
After all this changes you should also do this:
return out.reverse().toString();
instead of :
return out.toString();
Here is what I ended up with: http://pastebin.com/2TLqPUsH
(Change the name of the classes of course)