This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
The assignment was to create a postfix to infix converter using Stacks. The program compiles properly but when I tried to make a demo class, I received a null point exception line 32. Please share any observations, better coding conventions, or solutions.
import java.util.Stack;
public class PostfixtoInfix {
private String expression;
private Stack<Character> s;
Character pOpen = new Character('(');
Character pClose = new Character(')');
public String PostfixtoInfix(String e) {
expression = e;
String output = "";
for (int i = 0; i < e.length(); i++) {
char currentChar = e.charAt(i);
if (isOperator(currentChar)) {
while (!s.empty() && s.peek() != pOpen
&& hasHigherPrecedence(s.peek(), currentChar)) {
output += s.peek();
s.pop();
}
s.push(currentChar);
} else if (isOperand(currentChar)) {
output += currentChar;
} else if (currentChar == '(') {
s.push(currentChar);
} else if (currentChar == ')') {
while (!s.empty() && s.peek() != pClose) {
output += s.peek();
s.pop();
}
}
while (!s.empty()) {
output += s.peek();
s.pop();
}
}
return output;
}
public boolean isOperator(char c) {
if (c == '+' || c == '-' || c == '/' || c == '*' || c == '^')
return true;
return false;
}
public boolean isOperand(char c) {
if (c >= '0' && c <= '9')
return true;
if (c >= 'a' && c <= 'z')
return true;
if (c >= 'A' && c <= 'Z')
return true;
return false;
}
public int getOperatorWeight(char operator) {
int weight = -1;
switch (operator) {
case '+':
case '-':
weight = 1;
break;
case '*':
case '/':
weight = 2;
break;
case '^':
weight = 3;
}
return weight;
}
public boolean hasHigherPrecedence(char operator1, char operator2) {
int op1 = getOperatorWeight(operator1);
int op2 = getOperatorWeight(operator2);
if (op1 == op2) {
if (isRightAssociative(operator1))
return false;
else
return true;
}
return op1 > op2 ? true : false;
}
public boolean isRightAssociative(char op) {
if (op == '^')
return true;
return false;
}
}
To fix the NPE initialize your objects. Unlike C++, Stack<Character> s; is equivalent to Stack<Character> s = null;; not to Stack<Character> s = new Stack<>();!
Beware of == and != not behaving as you might expect for boxed objects.
Character a = new Character('A');
Character aa = new Character('A');
System.out.println(a == aa);
gives the (correct!) answer false.
They are different objects. If you want to compare for equality, use either:
System.out.println(a.equals(aa));
System.out.println((char)a==(char)aa);
The first uses an explicit method for comparing the object contents. The second one avoids this problem by using non-object primitives, where equality is bitwise, not reference-equality.
It appears that you declare a private member s, never assign anything to it, and then attempt to use it in expressions like s.empty() and s.pop(). If nothing is ever assigned to s, then it is null, and attempting to call a method on it will result in a NullPointerException.
To create an empty stack, you probably want to change the declaration to:
private Stack <Character> s = new Stack<Character>();
First of all, you have a method looking like a constructor:
public String PostfixtoInfix(String e) {
try changing it to something else, like:
public String transform(String e) {
Second, your s field never gets assigned a stack. Put
s = new Stack<Character>();
in your constructor. Also, new Character('a') != new Character('a'), because that will bypass automatic (pillowweight cached) boxing. Use instead just simple chars as pOpen and pClose.
Your access modifier may be preventing the program to access the stack.
Change:
private Stack <Character> s;
to:
protected Stack <Character> s;
Read more here
Related
This is my code:
import java.util.*;
public class TruthTable {
public static boolean evaluateExpression(String expression, boolean p, boolean q) {
Stack<Boolean> stack = new Stack<>();
Stack<Character> opStack = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == 'p') {
stack.push(p);
} else if (c == 'q') {
stack.push(q);
} else if (c == '¬') {
boolean b = stack.pop();
stack.push(!b);
} else if (c == '∧') {
// Check if the next character is a ¬ character.
if (i + 1 < expression.length() && expression.charAt(i + 1) == '¬') {
// If the next character is a ¬ character, pop the top of the stack and negate it,
// then push the conjunction of the negated value and the value of q.
boolean b = stack.pop();
stack.push(!(b && q));
// Increment the index to skip the ¬ character.
i++;
} else {
// If the next character is not a ¬ character, simply push the conjunction of the
// value of p and the value of q.
stack.push(stack.pop() && q);
}
} else if (c == '∨' || c == '→' || c == '↔' || c == '⊕' || c == '⊼' || c == '⊽') {
while (!opStack.isEmpty() && getPrecedence(c) <= getPrecedence(opStack.peek())) {
char op = opStack.pop();
applyOperator(op, stack);
}
opStack.push(c);
}
}
while (!opStack.isEmpty()) {
char op = opStack.pop();
applyOperator(op, stack);
}
return stack.pop();
}
private static void applyOperator(char op, Stack<Boolean> stack) {
boolean b1 = stack.pop();
boolean b2 = stack.pop();
switch (op) {
case '∧':
stack.push(b1 && b2);
break;
case '∨':
stack.push(b1 || b2);
break;
case '→':
stack.push(!b1 || b2);
break;
case '↔':
stack.push(b1 == b2);
break;
case '⊕':
stack.push(b1 != b2);
break;
case '⊼':
stack.push((b1 && b2) || (!b1 && b2) || (b1 && !b2));
break;
case '⊽':
stack.push(b1 && b2 && stack.pop());
break;
case '¬':
stack.push(!b1);
break;
}
}
private static int getPrecedence(char op) {
switch (op) {
case '¬':
return 3;
case '∧':
return 2;
case '∨':
return 1;
case '→':
return 0;
case '↔':
return 0;
case '⊕':
return 1;
case '⊼':
if (op == '∨' || op == '→' || op == '↔' || op == '⊕') {
return 2;
} else {
return 3;
}
case '⊽':
return 2;
default:
return -1;
}
}
public static void main(String[] args) {
String expression = "pq¬∨pq∧→";
System.out.println("p\tq\t(" + expression + ")");
for (boolean p : new boolean[]{true, false}) {
for (boolean q : new boolean[]{true, false}) {
System.out.println(p + "\t" + q + "\t" + evaluateExpression(expression, p, q));
}
}
}
}
The expected result is true false true false but it prints out false true false true and ive been trying to figure out how to fix it but I just cant. Will appreciate any help
Ive tried changing the precedence but it only produced the output True true true true
I don't expect many people will be able to help you, especially if you cannot see the logic error and you are the author!
When writing code like this, your best option is to write Unit Tests. Test parts of the implementation first and then give your algorithm expressions bit by bit and work up to more complex cases.
Note that your use of private static methods may frustrate your ability to test parts or mock out parts of the code. Go find an article about Unit Testing and Dependency Injection; it will be worthwhile your investment.
import stack.RStack;
public class Expressions {
private RStack data;
public Expressions() {
}
public boolean checkbalance(String expression) {
char charAt;
int i, len;
len = expression.length();
for(i = 0; i < len; i++) {
charAt = expression.charAt(i);
if(charAt == '(')
push(charAt);
else if(ch == ')') {
if(isEmpty())
return false;
else if((char)peek() == '(')
pop();
else
return false;
}
}
if(isEmpty())
return true;
else
return false;
}
public int precedence(char c) {
if((c == '*') || (c == '/'))
return 2;
else if((c == '+') || (c == '-'))
return 1;
else
return 0;
}
public boolean isOperand(char c) {
if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
return true;
else
return false;
}
public String infixToPostfix(String infix) {
char c;
int len, i;
String postfix = "";
len = infix.length();
for(i = 0; i < len; i++) {
c = infix.charAt(i);
if(isOperand(c))
postfix = postfix + c;
else if(c == '(')
push(c);
else if(c == ')') {
while((char)peek() != '(')
postfix = postfix + pop();
pop();
} else {
while(!isEmpty() && (precedence(c) <= precedence((char)peek())))
postfix = postfix + pop();
push(c);
}
}
while(!isEmpty())
postfix = postfix + pop();
return postfix;
}
public RStack getData() {
return data;
}
public void setData(RStack data) {
this.data = data;
}
}
Any idea on why do i always get "The method push(char) is undefined for the type Expressions", "the method peek() is undefined for the type Expressions", "The method isEmpty() is undefined for the type Expressions" and "The method pop() is undefined for the type Expressions"? when im trying to balance parenthesis for lab project and I always run into this issue
Your calls to push and pop do not exist. Therefore, the compiler complains.
If you meant to call those methods on your own class Expressions, you’ll need to define such methods. Do like you did with defining precedence and isOperand. See The Java Tutorials by Oracle.
If you meant to call those methods on an instance of another class, such as your mysterious RStack class, then you will need a reference to such an instance before you can call the methods. See The Java Tutorials.
By the way, the char type has been essentially broken since Java 2, and legacy since Java 5. As a 16-bit value, char is physically incapable of representing most characters.
To work with individual characters, use code point integer numbers. You’ll find various codePoint methods on classes such as String, StringBuilder, and Character.
I wrote this method to check to see if a words is a palindrome, but when it is a palindrome it keeps returning false
public boolean isPalindrome(String s){
int i;
int n = s.length();
Stack <Character> stack = new Stack <Character>();
for (i = 0; i < n/2; i++)
stack.push(s.charAt(i));
if (n%2 == 1)
i++;
while(!stack.empty( )) {
char c = stack.pop( );
if (c != s.charAt(i));
return false;
}
return true;
}
I'm not sure why you're not using { } brackets. Try to learn proper Java conventions early.
if (c != s.charAt(i)); // <- this semicolon is your problem
return false;
Is equivalent to:
if (c != s.charAt(i)) {
// Do nothing
}
// Do this no matter what
return false;
Furthermore, the logic on your for-loop may be flawed for similar reasons. Remove your semicolon, and better yet, practice always using brackets:
if (c != s.charAt(i)) {
return false;
}
#jhamon also points out that you never actually increment i in your while loop:
while(!stack.empty( )) {
char c = stack.pop( );
if (c != s.charAt(i)) {
return false;
}
i++;
}
I'm trying to solidify my understanding of stacks and operators by creating a simple calculator to process arithmetic expressions that involve parentheses. I feel like I have code that should work, but it's most certainly not giving me the right output.
Even though I have a method to evaluate each expression, when I try to return the number stack it does not print out any evaluated method but only all numbers inputted by the user. I want to deal with issues in input like mismatched operators or missing parentheses as well.
I attempt to run the code with simple expressions like 9 * 5 or something like (7 * 6) + (9 - 4) and it just returns the last double regardless.
Here's my code so far:
Main method
import java.util.Stack;
import javax.swing.JOptionPane;
public class Calculator {
// instance variables
private Stack < Double > nums;
private Stack < String > ops;
String list;
// constructor
public Calculator()
{
nums = new Stack < Double > ();
ops = new Stack < String > ();
}
// methods
public static boolean isDouble(String str) {
try {
Double.parseDouble(str);
} catch (NumberFormatException e) {
return false;
} catch (NullPointerException e) {
return false;
}
return true;
}
public static boolean isValidOp(String str) {
return (str == "(" || str == ")" || str == "^" || str == "*" || str == "/" || str == "+" || str == "-");
}
public int prec(String str) {
if (str == "(" || str == ")")
return 4;
if (str == "^")
return 3;
if (str == "*" || str == "/")
return 2;
if (str == "+" || str == "-")
return 1;
else
return -1;
}
public double applyOperator(double left, String op, double right) {
if (op == "+") {
return (left + right);
}
if (op == "-") {
return (left - right);
}
if (op == "*") {
return (left * right);
}
if (op == "/") {
return (left / right);
}
if (op == "^") {
return Math.pow(left, right);
} else {
throw new IllegalArgumentException("Not a valid operator");
}
}
public String evaluate(String str)
{
String [] tokens = str.split(" ");
for (int i = 0; i < tokens.length; i++)
{
if (isDouble(tokens [i]) == true)
{
nums.push(Double.parseDouble(tokens [i]));
}
if (tokens [i] == "(")
{
ops.push(tokens [i]);
}
if (tokens [i] == ")")
{
String op1 = ops.pop();
double num1 = nums.pop();
double num2 = nums.pop();
double result = applyOperator(num1,op1,num2);
nums.add(result);
}
if (tokens [i] == "+" || tokens [i] == "-" || tokens [i] == "*" || tokens [i] == "/" || tokens [i] == "^")
{
if(ops.isEmpty())
{
ops.push(tokens [i]);
}
else if (prec(tokens [i]) > prec(ops.peek()))
{
ops.push(tokens [i]);
}
else if (prec(tokens [i]) < prec(ops.peek()) && !ops.isEmpty() && ops.peek() != "(")
{
String ac1 = ops.pop();
double res1 = nums.pop();
double res2 = nums.pop();
double outcome = applyOperator(res1,ac1,res2);
nums.add(outcome);
}
}
}
while(!ops.isEmpty() && nums.size() > 1)
{
String ab = ops.pop();
double bb = nums.pop();
double cb = nums.pop();
double clac = applyOperator(bb,ab,cb);
nums.add(clac);
}
String fix = nums.pop().toString();
return fix;
}
}
Tester:
import javax.swing.JOptionPane;
public class AppforCalc {
public static void main(String [] args)
{
Calculator calc = new Calculator();
String reply = "yes";
String instructions = "Enter a mathematical expression. Separate everything with spaces";
while(reply.equalsIgnoreCase("yes"))
{
String expression = JOptionPane.showInputDialog(instructions);
String ans = calc.evaluate(expression);
reply = JOptionPane.showInputDialog("The solution is " + ans + "Try again?");
}
}
}
The main reason you algorithm fails is due to using == when trying to check for String equality.
In Java, == is a boolean operator which behaves identically for all operands, and checks the equality of the values of the operands. This means that primitives are checked as one might expect, but Strings, which are objects, will result in comparing the memory references of the two Strings, which will result in true only if the two Strings are actually the same String. This means that String equality checks must be done with the equals method.
There are more issues with the behavior of the calculator (algorithmic ones), but those will be easier to identify and fix after handling the String equality checks. One example of an issue that must be fixed is:
while(!ops.isEmpty() && nums.size() > 1)
{
String ab = ops.pop();
double bb = nums.pop();
double cb = nums.pop();
double clac = applyOperator(bb,ab,cb);
nums.add(clac);
}
The operands (bb and cb) are popped from a Stack, therefore they arrive in a reveresed order (when parsed, cb was pushed into the stack before bb). This means that cb is the leftside operand and bb is the rightside operand -> double clac = applyOperator(cb,ab,bb); The same refactoring should be done for all usages of the applyOperand method.
Another issue is the following:
else if (prec(tokens [i]) < prec(ops.peek()) && !ops.isEmpty() && ops.peek() != "(")
{
String ac1 = ops.pop();
double res1 = nums.pop();
double res2 = nums.pop();
double outcome = applyOperator(res1,ac1,res2);
nums.add(outcome);
}
An internal evaluation was made, but the triggering of the evaluation is the discvery of an operand with a lower presendence. The operand should be pushed into the operations stack after the evaluation:
else if (prec(tokens [i]) < prec(ops.peek()) && !ops.isEmpty() && ops.peek() != "(")
{
...
...
nums.add(outcome); // I highly suggest refactoring this to nums.push due to readability considerations
ops.push(tokens[i]);
}
References:
The difference between == and equals in Java
Guide for implementing a scientific calculator (in c++, use as an algorithmic reference)
The Shunting Yard Algorithm - As suggested by user207421
My Java Program is below. It's my training exercise. The one implements stack stucture for special type of string parsing(string with delimiter).
This delimiter-matching program works by reading characters from the string one at
a time and placing opening delimiters when it finds them, on a stack. When it reads
a closing delimiter from the input, it pops the opening delimiter from the top of the
stack and attempts to match it with the closing delimiter. If they’re not the same
type (there’s an opening brace but a closing parenthesis, for example), an error
occurs. Also, if there is no opening delimiter on the stack to match a closing one, or
if a delimiter has not been matched, an error occurs. A delimiter that hasn’t been
matched is discovered because it remains on the stack after all the characters in the
string have been read.
I use Eclipse. My output is here:
Please enter String:
{}
ch0 = {
ch1 = }
chLabel1 = **UNDEFINED CHAR(SQUARE WITH QUESTION MARK INSIDE IT)**
Error at }**
Could you explain value of chLabel?
As I understand operator "|" (here, cause two operands have boolean type) - is "lazy", shortcut version of "||" operator. I've tested the program after substitution "|" for "||"-result is the same.
public class MyStack {
private int top=0;
private int maxSize=0;
private char[] charArray=null;
public MyStack(int size){
maxSize=size;
top=0;
charArray=new char[maxSize];
}
public void push(char ch){
charArray[top++]=ch;
}
public char pop(){
return charArray[top--];
}
public boolean isEmpty(){
if(top==0)
return true;
else return false;
}
public boolean isFull(){
if(top==(maxSize-1))
return true;
else return false;
}
}
class StringParse {
private String stringForParsing = null;
public StringParse(String string) {
this.stringForParsing = string;
}
public void parser() {
char[] chArr = stringForParsing.toCharArray();
MyStack mySt = new MyStack(chArr.length);
for (int i = 0; i < chArr.length; i++) {
char ch = chArr[i];
switch (ch) {
case '{':
case '(':
case '[':
mySt.push(ch);
System.out.println("ch" + i + " = " + ch);
break;
case '}':
case ')':
case ']':
if (mySt.isEmpty())
System.out.println("Error at" + ch);
else {
char chLabel = mySt.pop();
System.out.println("ch" + i + " = " + ch);
System.out.println("chLabel" + i + " = " + chLabel);
if ((chLabel == '{') && (ch == '}') | (chLabel == '(') && (ch == ')') | (chLabel == '[') && (ch == ']'))
break;
else {
System.out.println("Error at " + ch);
break;
} // end of second else
} //end of first else
default:
break;
} //end of switch
} //end of parser method
}
} //end of class
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System. in ));
System.out.println("Please enter String:");
String s = br.readLine();
StringParse strP = new StringParse(s);
strP.parser();
}
}
There are two problems:
There's an error with the pop function.
Consider doing one push and then one pop:
top = 0
push
insert at position 0
set top to 1
pop
get position 1 (not set yet!)
set top to 0
You need to use pre-decrement instead of post-decrement, so charArray[top--] should be charArray[--top].
With this change I get chLabel1 = {.
Reiterating what I said in the comments...
| has higher precendence than &&(as opposed to || which has lower precedence) (see this),
thus a && b | c && d is the same as a && (b | c) && d,
as opposed to a && b || c && d which would be (a && b) || (c && d).
When changing the |'s to ||'s, I no longer get Error at }.
There may be a problem with your MyStack class
Using java.util.Stack gives me no error, just a "chLabel1 = {"
Error at } can be resolved by following Dukeling's advice and using || instead of |:
(chLabel == '{') && (ch == '}') || (chLabel == '(') && (ch == ')') || (chLabel == '[') && (ch == ']')
So, it looks like your code in MyStack.pop() doesn't return a valid char. I'll need to see your MyStack code to help further.