Validating expression using 2 Generic Stacks - java

The task is to implement a generic stack (can not use the libraries from java), make the user input an expression using true and false for booleans b1 and b2, logical operators (and, or, not, iff, implies) recognize if its boolean or operator and send to 2 stacks, then poping the stacks to evaluate if its a valid expression, i.e: input:(b1 and b2) implies b3 is a valid expression but B3 and (b2 or) is not, I have issues with the stack part, since the peek is not returning any element, here is my code so far, note: the charat is because I would be checking that the brackets are balanced as well:
public class MyStack<T> {
class StackOverFlowException extends RuntimeException{}
class EmptyStackException extends RuntimeException{}
private T[] stack;
private int top;
public MyStack(int size) {
this.stack = (T[]) new Object[size];
this.top = 0;
}
public boolean isEmpty() {
return this.top == 0;
}
public boolean isFull() {
return this.top == stack.length;
}
public void push(T x) {
if(top == stack.length) {
throw new StackOverFlowException();
}
else {
this.stack[top] = x;
top++;
}
}
public T pop() {
if(isEmpty()) {
throw new EmptyStackException();
}
else {
T value = this.stack[--top];
return value;
}
}
public T peek() {
return this.stack[top];
}
public static void main(String[] args) {
MyStack<String> tf = new MyStack(100);
MyStack<String> operators = new MyStack(100);
System.out.println("Please input the expression to evaluate: ");
Scanner scn = new Scanner(System.in);
String expression = scn.nextLine();
String tokens[] = expression.split(" ");
int n = tokens.length;
boolean P1 = true;
boolean P2 = true;
boolean result = true;
for(int i = 0; i < n; i++ ) {
String separate = tokens[i];
char x = separate.charAt(i);
if(tokens[i].equalsIgnoreCase("true")||tokens[i].equalsIgnoreCase("false")) {
tf.push(separate);
tf.peek();
}
else if(tokens[i].equalsIgnoreCase("and")||tokens[i].equalsIgnoreCase("not")||tokens[i].equalsIgnoreCase("or")||tokens[i].equalsIgnoreCase("implies")||tokens[i].equalsIgnoreCase("iff")) {
operators.push(separate);
}
else {
System.out.println("Expression not Valid!");
}
}
}

The top variable is being misinterpreted in the peek() method (as well as the isEmpty() method).
As implemented, top is a misnomer since it is actually the size of the stack (which may also be considered the index for the next element to be pushed). So your peek() method should be looking at the element before top.
Alternatively, you may to define top as the element at the top of the stack, as this is generally how you are using it elsewhere. In this case, you will need to define a flag value to indicate the stack is empty.
In any case, you need handle the empty Stack case in the peek() method.
public class MyStack {
private static final int EMPTY = -1;
private int top = EMPTY;
... other stuff ...
public boolean isEmpty() {
return EMPTY == top;
}
public T peek() {
if (ifEmpty()) {
throw new EmptyStackException("Cannot peek into empty Stack");
}
return stack[top];
}
}

Related

What is wrong with my Stack/isPalindrome() class/method?

For this method I needed to implement a custom made Stack class to see if the given string is a palindrome.
This is the custom Stack class:
public class Stack<T> {
private ArrayList<T> arrayList = new ArrayList<>();
private T head;
public Stack() {
arrayList.add(head);
}
#Override
public String toString() {
return arrayList.toString();
}
public boolean empty() {
return arrayList.size() == 1 ? true : false;
}
public T push(T element) {
arrayList.add(element);
head = element;
return element;
}
public T pop() {
T returnVal = arrayList.get(arrayList.size()-1);
if (!empty()) {
arrayList.remove(returnVal);
head = arrayList.get(arrayList.size()-1);
}
return returnVal;
}
public T peek() {
return head;
}
}
And this is the palindrome method:
public static boolean isPalindrome(String string) {
var stack = new Stack<Character>();
var flag = true;
for (int i=0; i<string.length(); i++)
stack.push(string.charAt(i));
if (string.charAt(0) == stack.peek()) {
for (int j=0; j<string.length(); j++) {
System.out.println(string.charAt(j) + " " + stack.peek());
if (string.charAt(j) != stack.pop()) {
flag = false;
break;
}
}
}
else
return false;
return flag;
}
When I run the method, it runs the loop only 2 times. The Stack object doesn't seem to pop. But when I tested the pop() method in the main method with just a set of different characters, it seemed to work. But in this isPalindrome() method, it doesn't seem to me that it works. Can someone please help out?
In your Stack.pop() method, the line arrayList.remove(returnVal); is not what you want.
It will remove the first occurrence of returnVal from the stack, but in pop() you need to remove the last occurrence of returnVal.
In Stack.pop() you need to remove the last element - which means you need to write
arrayList.remove(arrayList.size()-1);
Your complete Stack.pop() method would then be:
public T pop() {
T returnVal = arrayList.get(arrayList.size()-1);
if (!empty()) {
arrayList.remove(arrayList.size()-1);
head = arrayList.get(arrayList.size()-1);
}
return returnVal;
}

Palindrome with Array based stack and queue check

For an assignment we are applying what is said in the title. i have written all the code out, but when I am compiling the code i get four errors dealing with the line 19 of code.
while(!myQueue<String>.isEmpty() & !myStack.isEmpty()){
this is the full code if it also helps
import java.util.*;
public class Palindrome{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String userInputConversion;
String userInput;
MyStack myStack = new MyStack();
MyQueue<String> myQueue = new MyQueue<String>();
System.out.println("Enter in a possible Palindrome. ");
userInputConversion = scan.next();
userInput = userInputConversion.toLowerCase();
String s = new String();
for(int i = 0; i < userInput.length(); i++){
s = "" + userInput.charAt(i);
System.out.print(s);
myQueue.enqueue(s);
myStack.push(s);
}
while(!myQueue<String>.isEmpty() & !myStack.isEmpty()){
String deQueued = myQueue.dequeue();
String popped = myStack.pop();
if(deQueued == popped)
System.out.println("Input is a palindrome. ");
else
System.out.println("input isnt a palindrome. ");
}
}
}
class MyStack{
private String[] stack;
private int top;
public MyStack(){
stack = new String [100];
top = 0;
}
public String push(String pushP){
if(top >= stack.length){
System.out.println("Error: MyStack.push(): stack overflow");
return "yes";
}
stack[top] = pushP;
top++;
}
public String pop(){
if(top <= 0){
System.out.print("Error in MyStack.pop(): stack empty");
return "n";
}
top--;
return stack[top];
}
public boolean isEmpty(){
if(top == 0){
return true;
}
else{
return false;
}
}
`}
class MyQueue<String> implements Iterable<String> {
private String[] queue;
private int front = 0;
private int rear = 0;
private int currentSize = 0;
public MyQueue(){
queue = (String[])(new Object[1]);
front = 0;
rear = 0;
currentSize = 0;
}
public boolean isEmpty() {
return (currentSize == 0);
}
public int currentSize() {
return currentSize;
}
public void enqueue(String String) {
if (currentSize == queue.length - 1) {
resize(2 * queue.length);
}
queue[rear++] = String;
if (rear == queue.length) {
rear = 0;
}
currentSize++;
}
public String dequeue() {
if (this.isEmpty()) {
throw new RuntimeException("Tried to dequeue an empty queue");
}
else {
String itemToReturn = queue[front];
queue[front++] = null;
currentSize--;
if (front == queue.length) {
front = 0;
}
if (currentSize == queue.length / 4) {
resize(queue.length / 2);
}
return itemToReturn;
}
}
private void resize(int capacity) {
String[] newArray = (String[]) new Object[capacity];
for (int i = 0; i < currentSize; i++) {
newArray[i] = queue[(front + i) % queue.length];
}
queue = newArray;
front = 0;
rear = currentSize;
}
}
if anyone can help that would be great or give some pointers.
For your 2nd compilation error, The type MyQueue<String> must implement the inherited abstract method Iterable<String>.iterator(), you can either
implement the public Iterator<String> iterator() method
remove the implements Iterable<String> statement
or make MyQueue abstract
Making MyQueue abstract won't help you much & I also don't see any place in the code where you need an iterator or make use of the fact that MyQueue is Iterable. Being a queue, you would want to use its signature methods - enqueue & dequeue. So, you can safely go for option 2. Else to implement, this answer should help.
You also haven't implemented the concept of type arguments perfectly. You would want to use a Type Parameter in the class definition; e.g. class MyQueue<String> becomes class MyQueue<T>. Likewise the member variables & methods would also change.
You 3rd compilation error, This method must return a result of type String is simply because your push() method doesn't have a return statement at the end. It's better to simply make it void, since you're not using the returned String "yes" anywhere. For StackOverflow, you can throw an RuntimeException, just like you did in your dequeue.
Few pointers
You've made the classic mistake of comparing Strings with == instead of .equals() in the statement if (deQueued == popped).
Make it a practice to close your scanner/resources, even though in this case there's no harm.
You have a little logical error in your while loop that compares the characters - I'll let you figure that one out.
First of all your making things Complex, for a simple string why do you want use stack or queue . i guess below logic would help you
String original, reverse = "";
Scanner in = new Scanner(System.in);
System.out.println("Enter a string to check if it is a palindrome");
original = in.nextLine();
int length = original.length();
for ( int i = length - 1; i >= 0; i-- )
reverse = reverse + original.charAt(i);
if (original.equals(reverse))
System.out.println("Entered string is a palindrome.");
else
System.out.println("Entered string is not a palindrome.");

Postfix Notation Evaluation

I was working on my code and I'm stuck at this point.
My question is to evaluate postfix notation entered from the keyboard.
Here is my code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.NoSuchElementException;
interface Stack<E> {
// The elements of the Stack are any kind of objects
// Access methods:
public boolean isEmpty ();
// Returns true only if the stack is empty.
public E peek ();
// Returns the element on the top od the stack.
// Transformation methods:
public void clear ();
// Clears the stack.
public void push (E x);
// Adds x on the top of the stack.
public E pop ();
// Removes and returns the element on the top.
}
class ArrayStack<E> implements Stack<E> {
private E[] elems;
private int depth;
#SuppressWarnings("unchecked")
public ArrayStack (int maxDepth) {
// Creating new empty stack
elems = (E[]) new Object[maxDepth];
depth = 0;
}
public boolean isEmpty () {
// Returns true only if the stack is empty.
return (depth == 0);
}
public E peek () {
// Returns the element on the top od the stack.
if (depth == 0)
throw new NoSuchElementException();
return elems[depth-1];
}
public void clear () {
// Clears the stack.
for (int i = 0; i < depth; i++) elems[i] = null;
depth = 0;
}
public void push (E x) {
// Adds x on the top of the stack.
elems[depth++] = x;
}
public E pop () {
// Removes and returns the element on the top.
if (depth == 0)
throw new NoSuchElementException();
E topmost = elems[--depth];
elems[depth] = null;
return topmost;
}
}
public class PostFixEvaluation {
static int evaluatePostfix(char [] izraz, int n)
{
ArrayStack e;
char ch;
int op1,op2,result=0;
int i=0;
while(i<n)
{
if(Character.isDigit(izraz[i]))
{
ch=izraz[i];
e.push(ch);
}
else
{
ch=izraz[i];
op1 =(int)e.pop();
op2 =(int)e.pop();
if(ch=='+')
{
result=op1+op2;
}
if(ch=='-')
{
result=op1-op2;
}
if(ch=='/')
{
result=op1/op2;
}
if(ch=='*')
{
result=op1*op2;
}
e.push(result);
}
i++;
}
return result;
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String expression = br.readLine();
char exp[] = expression.toCharArray();
int rez = evaluatePostfix(exp, exp.length);
System.out.println(rez);
br.close();
}
}
My problem is at the evaluatePostfix function. I can't use the push and pop functions because it gives me this error:
PostFixEvaluation.java:100: error: variable e might not have been initialized
e.push(ch);
^
PostFixEvaluation.java:105: error: variable e might not have been initialized
op1 =(int)e.pop();
^
Note: PostFixEvaluation.java uses unchecked or unsafe operations.
Can anyone help me solve this problem?
static int evaluatePostfix(char [] izraz, int n)
{
ArrayStack e;
char ch;
int op1,op2,result=0;
int i=0;
while(i<n)
{
if(Character.isDigit(izraz[i]))
{
ch=izraz[i];
e.push(ch);
}
else
{
ch=izraz[i];
op1 =(int)e.pop();
op2 =(int)e.pop();
if(ch=='+')
{
result=op1+op2;
}
if(ch=='-')
{
result=op1-op2;
}
if(ch=='/')
{
result=op1/op2;
}
if(ch=='*')
{
result=op1*op2;
}
e.push(result);
}
i++;
}
return result;
}
Initialize e in function evaluatePostfix
ArrayStack<Character> e = new ArrayStack(10); // maxDepth = 10

Parenthesis Check within a Linked stack for infix to postfix

I have four classes.
One contains my linkedstack setup
One is infixtopostfix for prioritization and conversion
Parenthesis for matching
Postfix for evaluation
I have setup almost everything here but it is still returning false anyway I put it.
On another note my equals on !stackMatch.pop().equals(c) is not working due to it being a object type with '!' being a problem.
My programs are simple and straight forward:
LinkedStack.java
public class LinkedStack implements StackInterface {
private Node top;
public LinkedStack() {
top = null;
} // end default constructor
public boolean isEmpty() {
return top == null;
} // end isEmpty
public void push(Object newItem) {
Node n = new Node();
n.setData(newItem);
n.setNext(top);
top = n;
} // end push
public Object pop() throws Exception {
if (!isEmpty()) {
Node temp = top;
top = top.getNext();
return temp.getData();
} else {
throw new Exception("StackException on pop: stack empty");
} // end if
} // end pop
public Object peek() throws Exception {
if (!isEmpty()) {
return top.getData();
} else {
throw new Exception("StackException on peek: stack empty");
} // end if
} // end peek
} // end LinkedStack
InfixToPostfix.java
import java.util.*;
public class InfixToPostfix {
Parenthesis p = new Parenthesis();
LinkedStack stack = new LinkedStack();
String token = ""; // each token of the string
String output = ""; // the string holding the postfix expression
Character topOfStackObject = null; // the top object of the stack, converted to a Character Object
char charValueOfTopOfStack = ' '; // the primitive value of the Character object
/**
* Convert an infix expression to postfix. If the expression is invalid, throws an exception.
* #param s the infix expression
* #return the postfix expression as a string
* hint: StringTokenizer is very useful to this iteratively
*/
//public String convertToPostfix(String s) throws Exception {
//}
private boolean isOperand (char c){
return ((c>= '0' && c <= '9') || (c >= 'a' && c<= 'z'));
}
public void precedence(char curOp, int val) throws Exception {
while (!stack.isEmpty()) {
char topOp = (Character) stack.pop();
// charValueOfTopOfStack = topOfStackObject.charValue();
if (topOp == '(') {
stack.push(topOp);
break;
}// it's an operator
else {// precedence of new op
int prec2;
if (topOp == '+' || topOp == '-') {
prec2 = 1;
} else {
prec2 = 2;
}
if (prec2 < val) // if prec of new op less
{ // than prec of old
stack.push(topOp); // save newly-popped op
break;
} else // prec of new not less
{
output = output + topOp; // than prec of old
}
}
}
}
Parenthesis.java
import java.util.*;
public class Parenthesis{
private LinkedStack stack = new LinkedStack();
private Object openBrace;
private String outputString;
/**
* Determine if the expression has matching parenthesis using a stack
*
* #param expr the expression to be evaluated
* #return returns true if the expression has matching parenthesis
*/
public boolean match(String expr) {
LinkedStack stackMatch = new LinkedStack();
for(int i=0; i < expr.length(); i++) {
char c = expr.charAt(i);
if(c == '(')
stackMatch.push(c);
else if(c == ')'){
if (stackMatch.isEmpty() || !stackMatch.pop().equals(c))
return false;
}
}
return stackMatch.isEmpty();
}
}
Just wanted to give you all of it so you could help me. I have tests written already just struggling with the parenthesis problem of pushing it on the stack but unable to compare it to the closing parenthesis so it can check if there is enough while checking to be sure it is not empty.
The problem probably is, that you are trying to test if matching ( is currently on top of the stack when ) comes, but in c is acctual character, ), so you test if ) is on top of stack, not ( as you should.

Error java.lang.ArrayIndexOutOfBoundsException: -1 on my code

This is my code. There is an error showing on the terminal window. It says java.lang.ArrayIndexOutOfBoundsException: -1 at top--; and while (!stack.isEmpty()). Please help me solve this issue. I looked it up online but it did not help much. That is why I am asking you for help.
import java.util.*;
public class ArrayStack<T> implements StackADT<T>
{
private final static int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
public ArrayStack()
{
this(DEFAULT_CAPACITY);
}
public ArrayStack(int initialCapacity)
{
top = 0;
stack = (T[])(new Object[initialCapacity]);
}
public void push(T element)
{
if (size() == stack.length)
expandCapacity();
stack[top] = element;
top++;
}
private void expandCapacity()
{
stack = Arrays.copyOf(stack, stack.length * 2);
}
public T pop() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
top--;
T result = stack[top];
stack[top] = null;
return result;
}
public T peek() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
return stack[top-1];
}
public boolean isEmpty()
{
return stack.length == 0;
}
public int size()
{
return top;
}
public static void main(String[] args)
{
ArrayStack<Character> stack = new ArrayStack<Character>();
String sentence = " ", word;
Scanner in = new Scanner(System.in);
System.out.println("Enter a sentence:");
sentence= in.nextLine();
System.out.println("Reversing each word:");
Scanner sentenceScanner = new Scanner(sentence);
while(sentenceScanner.hasNext())
{
word = sentenceScanner.next();
for(int i= 0; i<word.length(); i++)
{
stack.push(word.charAt(i));
}
while (!stack.isEmpty())
{
System.out.print(stack.pop());
}
}
}
}
Your isEmpty() and pop() functions do not work together. Think about this: when you decrement top and set the index to null does the actual size of the list get adjusted? The fix will come by changing isEmpty() I am just using pop() as an example.
Your isEmpty() method is implemented incorrectly.
public boolean isEmpty()
{
return stack.length == 0;
}
It is currently comparing the size or capacity of of the stack array. This is a constant, it does not change. The value of
stack.length
is always equal to the value you used to initialize the array
new Object[length];
You should be comparing to the number of elements in your stack.
public boolean isEmpty()
{
return top == 0;
}

Categories

Resources