Implementing a Priority Queue as a Stack Java - java

I've implemented my program but I am getting an exception java.lang.ClassCastException
This is the code:
import java.util.NoSuchElementException;
public class BasePQStack<Item> implements Stack<Item> {
// TODO: implement this object.
private int N = 0;
private MaxPQ<Compare> pq = new MaxPQ<>();
private int count;
public BasePQStack() {
count = 0;
}
/**
* entry point for sample output..
*
* #param args
*/
public static void main(String[] args) {
Stack<Integer> S = new BasePQStack<Integer>();
S.push(new Integer(2));
S.push(new Integer(7));
Integer W = S.pop();
S.push(new Integer(8));
S.push(new Integer(5));
;
Integer X = S.pop();
Integer Y = S.peek();
S.push(new Integer(3));
Integer Z = S.pop();
System.out.println("Testing: ");
System.out.println(W);
System.out.println(X);
System.out.println(Y);
System.out.println(Z);
}
#Override
public Item push(Item item) {
Compare x = new Compare(item, count);
pq.insert(x);
count++;
N++;
return item;
}
#Override
public Item pop() {
if (isEmpty())
throw new NoSuchElementException("no such element");
else {
Item var = (Item) pq.delMax();
N--;
return var;
}
}
#Override
public Item peek() {
if (isEmpty())
throw new NoSuchElementException("no such element");
else {
Item var = (Item) pq.delMax();
push(var);
return var;
}
}
#Override
public boolean isEmpty() {
return N == 0;
}
#Override
public int size() {
return N;
}
public class Compare implements Comparable<Compare> {
private Item value;
private int a;
public Compare(Item value, int a) {
this.a = a;
this.value = value;
}
#Override
public int compareTo(Compare x) {
if (this.a > x.a)
return 1;
if (this.a < x.a)
return -1;
else
return 0;
}
public int getA() {
return this.a;
}
public Item getValue() {
return this.value;
}
#Override
public String toString() {
return "item {" + "value = " + value + ",a = " + a + '}';
}
}
}
The message I am getting from the console is BasePQStack$Compare cannot be cast to java.lang.Integer. I've tried to do many castings but could not figure anything out as it just led to more error
The output of the code should be:
7
5
8
3

You should probably replace this line
Item var = (Item) pq.delMax()
With
Item var = (Item) pq.delMax().getValue();
Because delMax() returns a compare object and you need a Item object.

From the Java documentation: Class cast exceptions are "thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance".
From the code you posted, it looks like it could be occurring when you attempt to cast something to an Item:
Item var = (Item) pq.delMax();
Probably because your queue does not contain objects of type Item, it contains objects of type Compare. In general be careful when you decide to downcast because the compiler errors are there to help you.

Your MaxPQ Key is of type Compare and when you push an Integer it gets wrapped in a Compare before being inserted into the MaxPQ.
The problem is when you pop or peek you do not do any unwrapping of the Compare to get back to the Integer. This is why you get a ClassCastException on any line that calls pop() or peek(). You are treating the Compare as if it is an Integer.
You need to modify your pop() and peek() methods as follows;
#Override
public Item pop() {
if (isEmpty()) {
throw new NoSuchElementException("no such element");
} else {
Item var = (Item) pq.delMax().getValue();
N--;
return var;
}
}
#Override
public Item peek() {
if (isEmpty()) {
throw new NoSuchElementException("no such element");
} else {
Item var = (Item) pq.delMax().getValue();
push(var);
return var;
}
}
Note the use of getValue(). This is what does the unwrapping I mentioned above i.e. it gets the Integer out of the Compare for you.

Related

Finding min and max value in a oop

Can I please get help with this java code? I am trying to output the min and max value of element from an array list but it's only outputting the first element added to the list and the last element added to the list. Can someone please tell me what the error might be?
Here is my code:
import java.util.ArrayList;
//import java.util.Collections;
public class ClassName{
private String fieldName;
private ArrayList<SubClass> list = new ArrayList<>();
public ClassName(String a) {
fieldName = a;
}
public String getFieldName() {
return fieldName;
}
public void addSub(SubClass b) {
list.add(b);
}
public void addSub(String b, double c) {
list.add(new SubClass(b, c));
}
public boolean haveSub(String b, double c) {
return list.contains(new SubClass(b, c));
}
public SubClass getSubByName(String b) {
String d = b;
for (Sub elem : list) {
d += elem;
return elem;
}
return null;
}
public SubClass closest() {
SubClass min = list.get(0);
for (int i = 1; i > list.size(); i++) {
SubClass minC = list.get(i);
if (min.equals(minC)) {
min = list.get(i);
}
}
return min;
}
public SubClassfurthest() {
SubClass max = list.get(0);
for (int i = 0; i < list.size(); i++) {
Planet maxC = list.get(i);
if (max.equals(maxC)) {
max = list.get(i);
}
}
return max;
}
#Override
public String toString() {
String s = "...text..." + fieldName + " ...text...:\n";
for (SubClass elem : list){
s += elem.toString();
}
return s;
}
}
From names being employed I believe you intend to compare by 'distance' (presumably distance from Sun?). Assuming this to be true and that the Planet class includes a getDistanceFromSun() method then you can do something like this. Finding the furthest Planet would work the same way except you switch the operator (or swap the operands).
public Planet findClosestToSun() {
Planet closest = null;
for (Planet planet : planets) {
if (null == closest || planet.getDistanceFromSun() < closest.getDistanceFromSun()) {
closest = planet;
}
}
return closest;
}

Comparing attribute of an object in implementation of priority queue

I've attempted to implement a priority queue using an Array of Objects "Queue Items" which have some data (a string), and an integer which is the priority. I am trying to make those items comparable so that when I add a new object to the queue I can iterate through the items and add the new item in the correct location and move all items that are now behind it backwards, however when I add a new item to the queue I get a null pointer exception. I'll include all my code, but the toString method was just copied in from a queue so it won't work as expected.
class QueueItem implements Comparable<QueueItem> {
String data;
int pri;
public QueueItem(String data, int pri) {
this.data = data;
this.pri = pri;
}
#Override
public int compareTo(QueueItem item) {
return this.data.compareTo(item.data);
}
}
public class PriorityQueue implements Queue<String> {
private QueueItem[] arr;
private int frontPos, backPos;
public PriorityQueue() {
arr = new QueueItem[20];
backPos = -1;
frontPos = 0;
}
public boolean isEmpty() {
return frontPos == (backPos + 1) % arr.length;
}
public String front() {
if (frontPos == (backPos + 1) % arr.length)
throw new QueueException("Empty Queue - front");
return arr[frontPos].data;
}
public int frontPri() {
if (frontPos == (backPos + 1) % arr.length)
throw new QueueException("Empty Queue - frontPri");
return arr[frontPos].pri;
}
public void addToPQ(String str, int x) {
if (arr.length==0) {
arr[frontPos] = new QueueItem(str, x);
frontPos++;
return;
}
else {
for (int i = 0; i < arr.length; i++) {
arr[i].compareTo(new QueueItem(str, x));
}
}
}
public void deleteFront() {
if (frontPos==(backPos+1)%arr.length) {
throw new QueueException("Empty Queue - deleteFront");
}
frontPos = (frontPos+1)%arr.length;
}
public String toString() {
if (frontPos == (backPos + 1) % arr.length) {
return "<>";
}
StringBuffer sb = new StringBuffer();
sb.append('<');
int pos = frontPos;
while (pos != backPos) {
sb.append(arr[pos]);
sb.append(',');
pos = (pos + 1) % arr.length;
}
sb.append(arr[backPos]);
sb.append('>');
return (sb.toString());
}
}
public interface Queue<String> {
public void addToPQ(String str, int x);
public void deleteFront();
public String front();
public boolean isEmpty();
public int frontPri();
}
class QueueException extends RuntimeException {
QueueException(String s) {
super("Tried to apply " + s + " to empty queue");
}
}
public class pqTest {
public static void main(String[] args) {
PriorityQueue pQ = new PriorityQueue();
if (pQ.isEmpty()) {
System.out.println("Queue is Empty - isEmpty");
}
pQ.addToPQ("Dog", 4);
pQ.addToPQ("Cat", 20);
pQ.deleteFront();
pQ.addToPQ("Fish", 2);
}
}
The problem is that arr is size 20 so the first element won't even be added through the if statement in your addToPQ method because arr.length != 0. So it will then go to your else statement, which iterates through every single element in arr. But arr has 20 null elements since each spot within the array of QueueItems has not been initialized. So you should change your condition in the if statement to frontPos == 0 and change the terminating condition in your loop to i < frontPos so that the method won't iterate through null elements within arr
public void addToPQ(String str, int x) {
if (frontPos==0) {
arr[frontPos] = new QueueItem(str, x);
frontPos++;
return;
}
else {
QueueItem item = new QueueItem(str, x);
for (int i = 0; i < frontPos; i++) {
arr[i].compareTo(item);
}
}
}
You get NullPointerException, because when you are adding second item, you go to else statment where you iterate over array with one non-null element and 19 nulls. So you need to change your code to check if array element at i is null and if it is, assign new element to it.

Removing an instance from a linked list which is using pairs

I am trying to remove an instance from my linked list however when i try searching for the object in the list it returns a value of -1 because it says its not there. what am i doing wrong. my application class is below and that calls the methods in my DataSet class
public class Application {
public static void main(String[] args) {
DataSet<String, Integer> db = new DataSet<>();
db.add("Theo", 4);
db.add("Maria", 5);
db.add("Adam", 4);
db.add("James", 5);
db.add("Charles", 7);
db.add("Nikki", 5);
db.add("Lynne", 5);
db.add("Kendal", 6);
db.add("Kerry", 5);
db.add("Janet", 5);
db.add("Gordon", 6);
db.add("Stepher", 7);
db.add("Sue", 3);
db.add("Ed", 2);
db.add("Adam", 4);
db.displayItems();
/*
System.out.println();
db.sortByFirst();
db.displayItems();
System.out.println();
db.sortBySecond();
db.displayItems();
System.out.println();
(db.findBySecond(5)).displayItems();
System.out.println();
(db.findByFirst("Adam")).displayItems();
System.out.println();
*/ System.out.println(db.remove("Adam", 4));
db.displayItems();
//System.out.println("size = " + db.size());
}
}
and the dataset is:
import java.util.LinkedList;
/**
*
* #param <T>
* #param <S>
*/
public class DataSet<T, S> {
LinkedList<Pair> datastructure = new LinkedList<>();
// Adds a new instance/item to the data structure.
public void add(T first, S second) {
Pair p = new Pair(first, second);
datastructure.add(p);
}
// Displays all itmes in the data structure.
public void displayItems() {
for (int i = 0; i < datastructure.size(); i++) {
System.out.println(datastructure.get(i));
}
}
// Removes all instances with matching criteria (first and second attribute values) and returns the number of instances removed.
public int remove(T first, S second) {
int count = 0;
Pair p = new Pair(first, second);
for (Pair datastructure1 : datastructure) {
Integer num = datastructure.indexOf(p);
System.out.println(num);
Boolean removed = datastructure.remove(p);
System.out.println(removed);
}
//will return count of how many removed
return count;
}
}
and the final class is the pair class
class Pair<T,S> {
private T first;
private S second;
public Pair(T theFirst, S theSecond) {
first = theFirst;
second = theSecond;
}
public T getFirst() {
return first;
}
public S getSecond() {
return second;
}
#Override
public String toString() {
return "(" + first + ", " + second + ")";
}
}
Like Adam pointed out the problem is that you're creating a new pair that is not in the list. What you want to do is to create an equals method in your Pair class and then iterate through your list comparing the elements using this equals method. The method should look like this:
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Pair other = (Pair) obj;
if (this.first != other.first) {
return false;
}
if (this.second != other.second) {
return false;
}
return true;
}
public int remove(T first, S second) {
int count = 0;
Pair p = new Pair(first, second);
for (Pair datastructure1 : datastructure) {
Integer num = datastructure.indexOf(p);
System.out.println(num);
Boolean removed = datastructure.remove(p);
System.out.println(removed);
}
//will return count of how many removed
return count;
}
In above remove method, you are creating a new Pair object. New object means new reference, So datastructure.indexOf(p) will always result -1.
Example:
datastructure contains three pairs:
Pair1 - reference 0x00000001 - "Theo",4
Pair2 - reference 0x00000002 - "Theo",5
Pair3 - reference 0x00000003 - "Theo",6
And we asked to remove "Theo",4. So `p` will be a new object like:
p - reference 0x00000004 - "Theo",4
This means that the reference of p will not match and it will not check the data. Modify the equals method of Pair class as follows:
#Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj instanceof Pair)
{
Pair pair = (Pair)obj;
if(pair.first.equals(this.first) && pair.second.equals(this.second)){
return true;
}
}
return false;
}

Evaluate a Postfix Expression Using a Singly Linked List

I'm writing a program that asks the user for a postfix expression, and then outputs the result to the expression. I am attempting to do this using a Singly Linked List, and using the Adapter Pattern to create a stack.
The code for the SinglyLinkedList class, the LinkedStack class, and the Stack implementation are all straight out of a Data Structures book that I own. So the SinglyLinkedListTest class is the only one that has my own code in it (and has errors).
I've written a program that simply uses a stack to evaluate a postfix expression before, but I'm getting confused this time with the extra classes included.
I'm sure I have a ton of errors, but the most obvious ones to me are in my SinglyLinkedListTest class, every time I push a value onto the stack. I know the issue is that I am attempting to push Objects and characters onto the stack instead of the arguments that match push(E e), but I don't know how to alter my code to make this work.
Any suggestions or input would be greatly appreciated.
Here is my Stack Implementation:
package PostFix;
public interface Stack<E>
{
int size();
boolean isEmpty();
void push(E e);
E pop();
}
Here is my LinkedStack class:
package PostFix;
public class LinkedStack <E> implements Stack<E>
{
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
public LinkedStack()
{
}
public int size()
{
return list.size();
}
public boolean isEmpty()
{
return list.isEmpty();
}
public void push(E e)
{
list.addFirst(e);
}
public E pop()
{
return list.removeFirst();
}
}
Here is my SinglyLinkedList class:
package PostFix;
public class SinglyLinkedList<E>
{
private static class Node<E>
{
private E element;
private Node<E> next;
public Node(E e, Node<E> n)
{
element = e;
next = n;
}
public E getElement()
{
return element;
}
public Node<E> getNext()
{
return next;
}
}
private Node<E> head = null;
private Node<E> tail = null;
private int size = 0;
public SinglyLinkedList()
{
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size == 0;
}
public void addFirst(E e)
{
head = new Node<>(e, head);
if (size == 0)
{
tail = head;
}
size++;
}
public E removeFirst()
{
if (isEmpty())
{
return null;
}
E answer = head.getElement();
head = head.getNext();
size--;
if (size == 0)
{
tail = null;
}
return answer;
}
}
Here is my final SinglyLinkedListTest class:
package PostFix;
import java.util.Scanner;
public class SinglyLinkedListTest
{
public static void main(String[] args)
{
Double num1, num2, answer;
char c;
Stack<Double> stack = new LinkedStack<>();
Scanner input = new Scanner(System.in);
System.out.println("Enter the expression you would like to evaluate: ");
String someString = input.nextLine();
for (int index = 0; index < someString.length(); index++)
{
c = someString.charAt(index);
if (Character.isDigit(c))
{
stack.push((double)Character.digit(c, 10));
}
else if (c == '+')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1+num2;
stack.push(answer);
}
else if (c == '-')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1-num2;
stack.push(answer);
}
else if (c == '*')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1*num2;
stack.push(answer);
}
else if (c == '/')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1/num2;
stack.push(answer);
}
}
System.out.println("The result is: " + stack.pop());
}
}
Stack<String> buffer = new LinkedStack<>();
Poor name: call it stack.
You've declared it as Stack<String> but you're pushing chars:
buffer.push(someString.charAt(index));
and Objects:
buffer.push(answer);
and popping ints:
num1 = buffer.pop();
You are never either pushing or popping strings.
Just make up your mind. You should be pushing and popping ints, or longs, or doubles, or BigDecimals, depending on what precision you need.
EDIT
buffer.push((double)c);
is invalid. You're pushing the ASCII value, not the numeric value it corresponds to. You need
buffer.push((double)Character.digit(c, 10));
You also need an else after each if block: if the character is a digit, it won't be a +, and if it's a + it won't be a -, etc.

First year prgorammer needs help with a nullpointer exception in java

As a portion of a first year assignment, I need to create a class which uses a provided linked list implementation to implement a provided stack interface which is then tested by another provided class. I was able to easily complete the assignment using my own LL; however, I was told that I needed to use the one provided.
Exception in thread "main" java.lang.NullPointerException
at StackLL.<init>(StackLL.java:21)
at StackTester.main(StackTester.java:91)
Now I get null pointer exceptions whenever I try and run it. I thought this was being caused by the tester trying to grab the size of the list before the LL is initialized, but that doesn't seem to be the case and I am stumped.
Any tips on what I can do to fix the bug so that I can hand in the rest of the assignment? Thanks :)
The provided linked list implementation
LinkedList.java
/**
* LinkedList - a simple linked list of ints
*/
public class LinkedList
{
Node head;
int count;
public LinkedList ()
{
head = null;
count = 0;
}
/**
* Adds the given item to the start of the list
*/
public void addToStart (int item)
{
Node newNode = new Node();
newNode.value = item;
if (head != null)
newNode.next = head;
head = newNode;
count++;
}
/**
* Adds the given item to the end of the list
*/
public void addToEnd (int item)
{
if (size() == 0)
{
addToStart (item);
}
else
{
Node n = head;
while (n.next != null)
n = n.next;
n.next = new Node(item);
count++;
}
}
/**
* Remove and return the first item in the list
*/
public int removeFromStart ()
{
if (size() == 0)
throw new EmptyListException();
int valtoReturn = head.value;
head = head.next;
count--;
return valtoReturn;
}
/**
* Remove and return the last item in the list
*/
public int removeFromEnd ()
{
if (size() == 0)
throw new EmptyListException();
if (size() == 1)
return removeFromStart();
else
{
Node n = head;
while (n.next.next != null)
n = n.next;
int valtoReturn = n.next.value;
n.next = null;
count--;
return valtoReturn;
}
}
/**
* Return the number of items contained in this list
*/
public int size ()
{
return count;
}
/**
* A basic node class
*/
private class Node
{
int value;
Node next;
Node()
{
}
Node (int value)
{
this.value = value;
}
}
// random testing code for the Linked List
public static void main (String [] args)
{
LinkedList l = new LinkedList();
l.addToStart (5);
int val = l.removeFromStart();
System.out.println (val == 5 ? "passed" : "failed");
System.out.println (l.size() == 0 ? "passed" : "failed");
for (int x = 0; x < 10; x++)
l.addToEnd (x);
System.out.println (l.size() == 10 ? "passed" : "failed");
while (l.size() > 0)
System.out.print (l.removeFromEnd() + " ");
System.out.println ();
}
}
/**
* The exception class when a removal action is performed on
* an empty list.
*/
class EmptyListException extends RuntimeException
{
public EmptyListException ()
{
super();
}
public EmptyListException (String s)
{
super(s);
}
}
My implementation
StackLL.java
/**
* A linked list implementation of the Stack ADT.
*
*/
public class StackLL implements Stack
{
// The linked list that will contain the values in the stack
private LinkedList values;
public int size()
{
return values.size();
}
public boolean isEmpty()
{
if (values.size() <= 0) {
return true;
}
return false;
}
public void push(int element)
{
values.addToStart(element);
}
public int pop() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else {
return values.removeFromStart();
}
}
public int peek() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else { //This is a pretty silly way to do this, but I can't think of any other way without making my own linked list method.
int elementVal = values.removeFromStart();
values.addToStart(elementVal);
return elementVal;
}
}
}
The Provided Interface
Stack.java
/**
* Stack.java
*
* A specification of the Stack ADT
*
*/
public interface Stack
{
int size();
boolean isEmpty();
void push (int element);
int pop() throws StackEmptyException;
int peek() throws StackEmptyException;
}
class StackEmptyException extends Exception
{
public StackEmptyException ()
{
super();
}
public StackEmptyException (String s)
{
super(s);
}
}
The Tester
StackTester.java
/**
* StackTester.java
*
* Some test cases for a stack.
*/
public class StackTester
{
public static void testOne (Stack s)
{
try
{
if (s.size() != 0 || !s.isEmpty())
System.out.println("1: Failed size or isEmpty.");
s.push(1);
s.push(2);
if (s.size() != 2 || s.isEmpty())
System.out.println("2: Failed size or isEmpty.");
if (!(s.pop() == 2))
System.out.println("3: Failed pop");
if (!(s.peek() == 1))
System.out.println("4: Failed peek");
if (!(s.pop() == 1))
System.out.println("5: Failed pop");
if (s.size() != 0 || !s.isEmpty() )
System.out.println("6: Failed size or isEmpty.");
}
catch (StackEmptyException e)
{
System.out.println(e);
}
}
public static void testTwo (Stack s)
{
try
{
for (int i = 0; i < 100; i++)
{
s.push(i);
}
if (s.size() != 100)
System.out.println("7: Failed size.");
for (int i = 99; i >= 0; i--)
{
if (!(s.pop() == i))
{
System.out.println("Failed pop for: " + i);
break;
}
}
}
catch (StackEmptyException e)
{
System.out.println("Failed testTwo.");
System.out.println(e);
}
}
public static void testThree (Stack s)
{
try {
while (!s.isEmpty())
s.pop();
}
catch (StackEmptyException e) {
System.out.println ("Failed empty stack test (popped on a non empty stack threw exception)");
}
try
{
s.pop();
System.out.println("Failed empty stack test.");
}
catch (StackEmptyException e)
{
/* If we get here, we
* passed the previous test.
*/
}
}
public static void main (String args[])
{
Stack s1 = new StackLL();
Stack s2 = new StackLL();
Stack s3 = new StackLL();
testOne(s1);
testTwo(s2);
testThree(s3);
}
}
You have private LinkedList values; in StackLL.
That says "this class has a field called values of type LinkedList". It does not assign an object to values, so when you try to access it, a NullPointerException occurs.
You should be able to fix it by assigning a value to values, i.e.:
private LinkedList values = new LinkedList();
(I don't know if you've learned about generics yet, but if you have, remember to add the type, e.g. LinkedList<Person>.)
Look at the line of code given in the error message (I'm assuming its the return statement in your size() function) and think about the meaning of NullPointerException -- the variable which is null is not yet initialized. Then ask yourself, do I expect this variable to be initialized here? If yes, then ask why isn't it and where should it be initialized? If no, then you have a logic error at the given location.
You aren't ever instantiating a LinkedList object in StackLL. So the first time you try to access it, it blows a NPE.

Categories