What is causing me to get this EmptyStackException? - java

My program takes a postfix expression and changes it to an infix expression.
I have included two reasons for error in the code which is if the program does not have enough operators and if the input is not a valid number or operator.
The errors are caught when I put in input that is not good, however, when putting correct input in the scanner it gives me this error:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at PostfixToInfix.change(PostfixToInfix.java:67)
at PostfixToInfix.main(PostfixToInfix.java:27)
What needs to be changed in my code?
Code:
import java.util.Scanner;
import java.util.Stack;
import java.util.EmptyStackException;
public class PostfixToInfix
{
int x = 0;
public static void main(String[] args)
{
PostfixToInfix exp = new PostfixToInfix();
Scanner stdin =new Scanner(System.in);
try {
boolean inputNeeded = true;
int value = 0;
while(inputNeeded){
System.out.print("Postfix : ");
if(stdin.hasNextInt()){
inputNeeded = false;
}
else{
throw new Error("Not a number or valid operator");
}
}
String pf = stdin.nextLine().replaceAll("\\s+", "");
System.out.println("Infix : "+exp.change(pf));
}
catch (EmptyStackException e) {
System.out.println("Too few operators to produce a single result.");
}
}
static boolean isOperator(char c)
{
if(c == '+' || c == '-' || c == '*' || c =='/' || c == '^')
{
return true;
}
return false;
}
boolean empty() //whether the stack is empty
{
return x == 0;
} // end empty
public String change(String pf)
{
Stack<String> s = new Stack<>();
for(int i = 0; i < pf.length(); i++)
{
char z = pf.charAt(i);
if(isOperator(z))
{
String x = s.pop();
String y = s.pop();
s.push("("+y+z+x+")");
}
else
{
s.push(""+z);
}
}
return s.pop();
}
}

Consider the input 1 1 +.
The Scanner reads the 1 and stores it in value.
The Scanner reads the remaining string and a modified version of it ("1+") is stored in pf, which is passed as an argument to the change method.
charAt returns the first character of pf (a '1'), isOperator returns false, and the else block executes, which pushes "1" to the Stack.
charAt returns the second character of pf (a '+'), isOperator returns true, and the if block executes.
pop is called once, removing the only element in the stack, "1", and assigning it to x. The stack is now empty, and the second call to pop results in the EmptyStackException.
This is how to debug your code if your IDE does not have a debugger already. Through this, you should find that using nextInt is the issue, since only one number will be present in the remaining string when the if block is expecting two.

Related

program to find if two characters in String in a row are digits does not work in java

I have the code below, which I want to take input from the keyboard and show me if the input contains 2 digits in a row. If so, I want to get false printed out in the console, otherwise true. It works fine, except when the first 2 characters of the input are digits. In that case, I still get true in the console. Can anyone understand why? Thanks in advance
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System. in );
System.out.println("Enter:");
String s = sc.nextLine();
if (checkDigit(s)) {
System.out.println("false");
} else {
System.out.println("true");
}
}
public static boolean checkDigit(String s) {
boolean b = true;
char[] c = s.toCharArray();
for (int i = 0; i < c.length - 1; i++) {
if (Character.isDigit(c[i]) && Character.isDigit(c[i + 1])) {
b = true;
} else {
b = false;
}
}
return b;
}
}
You continue to check the input string even when you already found the result. As noted by #Stultuske, you overwrite the value of the variable b, so your code will only return true, if the last two chars are digits.
You would need to return from the loop if there are two digits in a row:
public static boolean checkDigit(String s) {
char[] c = s.toCharArray();
for(int i=0; i < c.length-1; i++) {
if(Character.isDigit(c[i]) && Character.isDigit(c[i+1])) {
return true;
}
}
return false;
}
UPDATE: in fact there was an error in the snippet, as it was returning too early from the loop. Fixed now.
The problem is that you overwrite the value on each loop iteration, so you only get true if the last pair of characters match. But Krypt1 already said this.
An alternative implementation using streams (because all the kids want to use Streams these days):
return IntStream.range(0, str.length()-1)
.anyMatch(i -> Character.isDigit(str.charAt(i)) && Character.isDigit(str.charAt(i+1)));
use Character.isDigit(char) method in your if condition and return true; rather than store b=true as that may get overwritten in next iteration.
you can also use regular expression. String's matches(pattern) method for this purpose.
Try using the following regex
Pattern pattern = Pattern.compile("[0-9]{2}");
Matcher matcher = pattern.matcher("your input string");

Palindrome for Integers and Strings Java

I'm trying to create Palindrome app for Integers and Strings in Java, I'm having an issue with my if statement, it outputs incorrect/repeating True and False statements:
import java.util.Scanner;
import java.io.*;
public class Palindrome {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
System.out.println("Enter characters to check for Palindrome: ");
if ( user_input.hasNextInt() ){
String intToString = String.valueOf(user_input.nextInt()).toString();
String reversedInt = new StringBuffer(intToString).reverse().toString();
for (int i = 0; i<intToString.length(); i++) {
if (intToString.charAt(i) != reversedInt.charAt(i)) {
System.out.println("False");
}
else {
System.out.println("True");
}
}
}
else if ( user_input.hasNextLine() ) {
String user_string = user_input.nextLine().replaceAll(" ", "").toLowerCase();
StringBuilder user_mutable_string = new StringBuilder(user_string);
user_mutable_string.reverse();
if (user_string.equals(user_mutable_string.toString())) {
System.out.println("True");
}
else {
System.out.println("False");
}
}
else {
System.out.println("Bonkers!");
}
}
}
Your issue is with the for loop, which you don't need. You have already reversed the numbers and converted both the original and reversed numbers to a String. All you need to do then is to compare them. Change the for loop to a simple if:
if (intToString.equals(reversedInt)) {
System.out.println("True");
}
else {
System.out.println("False");
}
Since you are using a loop to check the whole string, you don't want to output True immediately, since you don't know yet at that point. It could be, that the next char won't pass the condition.
You should use a boolean variable instead, like this
boolean isPalindrome = true; // let's assume it will be ok
for (int i = 0; i<intToString.length(); i++) {
if (intToString.charAt(i) != reversedInt.charAt(i)) {
isPalindrome = false;
}
}
System.out.println(isPalindrome);

Reverse Polish Notation Code Review

I've been trying to solve this question on SPOJ: http://www.spoj.com/problems/ONP/.
I've tried to implement a two Stack solution for the problem stated above. It works fine on my system, but I get a 'Wrong Answer' every time I try to submit the following code to the SPOJ Engine.
import java.io.*;
import java.util.Stack;
import java.util.Scanner;
public class InfixToPostfix {
public static String postfixString(String expression) {
Stack <Character> valueStack = new Stack <Character>();
Stack <Character> operatorStack = new Stack <Character>();
char[] tokens = expression.toCharArray();
for(char c : tokens) {
if(c == '('){
continue;
}
else if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
operatorStack.push(c);
continue;
}
else if(c == ')') {
valueStack.push(operatorStack.peek());
operatorStack.pop();
continue;
}
else {
valueStack.push(c);
continue;
}
}
return valueStack.toString();
}
public static void main (String [] args)throws java.lang.Exception {
String inputString = "";
int n1;
Scanner numberOfTestCases = new Scanner(System.in);
try
{
n1 = numberOfTestCases.nextInt();
StringBuilder[] sbuf = new StringBuilder[n1];
Scanner inputExpression = new Scanner(System.in);
for(int i = 0; i < n1; i++) {
sbuf[i] = new StringBuilder();
if(inputExpression.hasNextLine()) {
inputString = inputExpression.nextLine();
sbuf[i].append(postfixString(inputString).replaceAll("\\[", "").replaceAll("]", "").replaceAll(", ", ""));
}
else {
break;
}
}
for(int i = 0; i < n1; i++) {
System.out.println(sbuf[i].toString());
}
}
catch (Exception e) {
// System.out.println("");
System.out.println(e.getMessage());
// numberOfTestCases.next();
}
System.exit(0);
}
}
I can't figure out where I'm going wrong; I've tried all possible test cases.
P.S.: The problem assumes all inputs to be parenthesized; there's no need to include any code for resolving operator precedence.
return valueStack.toString();
This doesn't return the required format: it returns a comma-separated format bounded by [ and ], which isn't what is specified.
But I'm sure there are other problems.
I don't see anything in the problem statement that corresponds to your PS: on the contrary, it specifically mentions operator precedence.
Are you sure you've 'tried all possible test cases'? Try (1+2)/3 and 1+3/2.
You're peeking something you haven't pushed in the case of ')'.
I don't see why you need two stacks either.
Given the problem statement, what you need is either a recursive-descent expression parser or the Dijkstra Shunting-yard algorithm.

Iterating over a String to check for a number and printing out the String value if it doesn't have a number

I have set up my function for checking for a number in a String, and printing out that String if it has no numbers, and putting up an error message if it does. Here is my code:
public class NumberFunction
{
public boolean containsNbr(String str)
{
boolean containsNbr = false;
if(str != null && !str.isEmpty())
{
for(char c : str.toCharArray())
{
if(containsNbr = Character.isDigit(c))
{
System.out.println("Can't contain numbers in the word.");
break;
}
else
{
System.out.println(str);
}
}
}
return containsNbr;
}
}
import com.imports.validationexample.function.NumberFunction;
public class Main
{
public static void main(String[] args)
{
NumberFunction nf = new NumberFunction();
System.out.println(nf.containsNbr("bill4"));
}
}
I am trying to get it to print out the result to the console, but the result keeps printing multiple times and prints the boolean value, which I do not want, something like this:
bill4
bill4
bill4
bill4
Can't contain numbers in the word.
true
Why is this happening? I've tried casting but that hasn't worked out either. Any help would be much appreciated.
Well you're assingning the value to containsNbr.
if(containsNbr = Character.isDigit(c))
change that line for:
if(Character.isDigit(c)) { //will evaluate if 'c' is a number
containsNbr = true;
break;
}
Also don't have an else, put this after the for-each loop:
for(char c : str.toCharArray())
if(Character.isDigit(c)) { //will evaluate if 'c' is a number
containsNbr = true;
break;
}
}
if(containsNbr) {
System.out.println("Can't contain numbers");
}
else {
System.out.println(str);
}
So it will print only once the str word instead of n times.
You were printing it many times because your else was inside the for-loop. Taking it out, will solve the issue.
Also convert the function from boolean to void so you won't print that true or false at the end.

JAVA: Parentheses match method not printing

Hey I am doing a programming assignment and we have to match parentheses in a String. We have to output an Error message such as the following:
Sample I/O:
Enter a string to test:
( < [ { } ( { > ) ] >
error: '>' does not match with '{'.
I am trying to print this message in my isBalanced() method however it will not print the System.out.println() however it is reaching that code block (otherwise it would never return false) which it is. I think the problem lies in my main method but I have been trying for a while now and I am stumped!
Any help is appreciated.
Thanks,
Kyle.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.EmptyStackException;
import java.util.Stack; //using java's default stack in this case as it has more extraneous error checking
public class Question3 {
private static final String OPEN = "([{<";
private static final String CLOSED = ")]}>";
public static void main(String[] args) throws IOException {
BufferedReader inKb = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("Enter a test string:");
String input = inKb.readLine();
boolean successful = isBalanced(input);
System.out.println(successful);
}
public static void printError(char ch, char expected) {
System.out.println("Error: '" + ch + "' does not match with '"
+ expected + "'");
}
private static boolean isOpen(char bracket) {
return OPEN.indexOf(bracket) >= 0;
}
private static boolean isClosed(char bracket) {
return CLOSED.indexOf(bracket) >= 0;
}
private static boolean matches(char openBracket, char closedBracket) {
return OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
}
public static boolean isBalanced(String input) {
Stack<Character> stack = new Stack<Character>();
try {
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (isOpen(ch)) {
stack.push(ch);
} else if (isClosed(ch)) {
char corBracket = stack.pop(); // pop corresponding bracket
if (!matches(ch, corBracket)) {
System.out.println("Print Test!"); //Not printing?
return false;
}
}
}
} catch (EmptyStackException ex) {
return false;
}
return stack.isEmpty(); //if stack is empty then the corresponding bracket wasn't found!
}
}
In
if (!matches(ch, corBracket)) {
ch is the closing and corBracket is the opening. You need to reverse them
if (!matches(corBracket, ch)) {
to match the method semantics
private static boolean matches(char openBracket, char closedBracket) {
boolean value = OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
return value;
}
You use descriptive names in the matches method. You should do the same everywhere else.
This is an example where it would be useful to use a debugger.
Debugging your application with the input ( < ) tells me that !matches(ch, corBracket) is evaluated as false and therefore your if statement is ignored. This leads us to believe that your matches(char, char) method is incorrect.
If you try changing your matches method to the following:
private static boolean matches(char openBracket, char closedBracket) {
int i1 = OPEN.indexOf(openBracket);
int i2 = CLOSED.indexOf(closedBracket);
return (i1 == i2);
}
You will see in your debugger that i1 and i2 are both -1 (the return value of indexOf in the case of no occurrence) and since -1 == -1 evaluates to true, !(-1 == -1) evaluates to false, as expected.
Hope this helps.
You are looking for opening brakets in CLOSED and for closing brackets in OPENED!
you need to change
return OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
into
return CLOSED.indexOf(openBracket) == OPEN.indexOf(closedBracket);
or just swap the parameters in your call
matches(corBracket, ch)
instead of
matches(ch, corBracket)
debuging into the call that function would have show you that OPEN.indexOf(openBracket) return -1 witch is supicious since you are expecting to find what you are searching for i.e. an index which is greater or equal than 0 and less than OPEN.length()

Categories