I am using the following code to make an immutable queue.
import java.util.NoSuchElementException;
import java.util.Queue;
public class ImmutableQueue<E> {
//Two stacks are used. One is to add items to the queue(enqueue) and
//other is to remove them(dequeue)
private ImmutableQueue(ReversableStack<E> order, ReversableStack<E> reverse) {
this.order = order;
this.reverse = reverse;
}
//initially both stacks are empty
public ImmutableQueue() {
this.order = ReversableStack.emptyStack();
this.reverse = ReversableStack.emptyStack();
}
public ImmutableQueue<E> enqueue(E e) {
if (null == e)
throw new IllegalArgumentException();
return new ImmutableQueue<E>(this.order.push(e), this.reverse);
}
public ImmutableQueue<E> dequeue() {
if (this.isEmpty())
throw new NoSuchElementException();
if (!this.reverse.isEmpty()) {
return new ImmutableQueue<E>(this.order, this.reverse.tail);
} else {
return new ImmutableQueue<E>(ReversableStack.emptyStack(),
this.order.getReverseStack().tail);
}
}
private static class ReversableStack<E> {
private E head; //top of original stack
private ReversableStack<E> tail; //top of reversed stack
private int size;
//initializing stack parameters
private ReversableStack(E obj, ReversableStack<E> tail) {
this.head = obj;
this.tail = tail;
this.size = tail.size + 1;
}
//returns a new empty stack
public static ReversableStack emptyStack() {
return new ReversableStack();
}
private ReversableStack() {
this.head = null;
this.tail = null;
this.size = 0;
}
//Reverses the original stack
public ReversableStack<E> getReverseStack() {
ReversableStack<E> stack = new ReversableStack<E>();
ReversableStack<E> tail = this;
while (!tail.isEmpty()) {
stack = stack.push(tail.head);
tail = tail.tail;
}
return stack;
}
public boolean isEmpty() {
return this.size == 0;
}
public ReversableStack<E> push(E obj) {
return new ReversableStack<E>(obj, this);
}
}
private ReversableStack<E> order;
private ReversableStack<E> reverse;
private void normaliseQueue() {
this.reverse = this.order.getReverseStack();
this.order = ReversableStack.emptyStack();
}
public E peek() {
if (this.isEmpty())
throw new NoSuchElementException();
if (this.reverse.isEmpty())
normaliseQueue();
return this.reverse.head;
}
public boolean isEmpty() {
return size() == 0;
}
//returns the number of items currently in the queue
public int size() {
return this.order.size + this.reverse.size;
}
public static void main(String[] args)
{
ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
newQueue.enqueue(5);
newQueue.enqueue(10);
newQueue.enqueue(15);
int x = newQueue.size();
//ImmutableQueue<Integer> x = newQueue.dequeue();
System.out.println(x);
}
}
But whenever I try to do a dequeue, I get a NoSuchElementException. Also, the newQueue.size function also returns 0.
What am I doing wrong ?
Thanks
You are missing the new ImmutableQueue reference..
since enqueue() method returns a new instance of ImmutableQueue
public ImmutableQueue<E> enqueue(E e) {
if (null == e)
throw new IllegalArgumentException();
return new ImmutableQueue<E>(this.order.push(e), this.reverse);
}
But on your main method you are discarding that object
public static void main(String[] args)
{
ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
newQueue.enqueue(5);
newQueue.enqueue(10);
newQueue.enqueue(15);
int x = newQueue.size();
//ImmutableQueue<Integer> x = newQueue.dequeue();
System.out.println(x);
}
change your call to:
newQueue = newQueue.enqueue(5);
int x = newQueue.size();
System.out.println(x);
and you will see the size will change
Related
interface Iterator {
boolean hasnext();
int next();
}
class practice5 {
public static void main(String a[]) {
Stack s = new Stack();
Queue q = new Queue();
Linkedlist l = new Linkedlist();
s.push(100);
s.push(200);
q.Enque(300);
q.Enque(400);
l.add(500);
l.add(600);
Iterator itr;
itr = s;
while (!itr.hasnext()) {
System.out.println(itr.next());
}
itr = q;
while (!itr.hasnext()) {
System.out.println(itr.next());
}
itr = l;
while (itr.hasnext()) {
System.out.println(itr.next());
}
}
}
class Stack extends Iterator {
private int stack[];
private int top;
public Stack() {
stack = new int[10];
top = -1;
}
public void push(int val) {
top++;
stack[top] = val;
}
public boolean hasnext() {
if (top >= 0) {
return false;
} else {
return true;
}
}
public int next() {
return (stack[top--]);
}
}
class Queue extends Iterator {
private int queue[];
private int front, rear;
public Queue() {
queue = new int[10];
front = 0;
rear = 0;
}
public void Enque(int val) {
queue[rear] = val;
rear++;
}
public boolean hasnext() {
if (front < rear) {
return false;
} else {
return true;
}
}
public int next() {
return (queue[front++]);
}
}
class Linkedlist extends Iterator {
private int data;
private Linkedlist nw, next, prev, first, guest;
public Linkedlist() {
nw = next = prev = first = null;
}
public void add(int val) {
nw = new Linkedlist();
nw.data = val;
if (first == null) {
prev = first = nw;
} else {
prev.next = nw;
prev = nw;
}
}
public boolean hasnext() {
if (guest != 0) {
return true;
} else {
return false;
}
}
public int next() {
int curval;
curval = first.data;
first = first.next;
return (curval);
}
}
I'm expecting that I get an output for the above code.
I need to know if I'm extending the Stack, Queue and LinkedList classes wrongly with the interface class. Whenever I'm pass the iterator class object the instance of my child class objects, I am getting an error.
Also, in the LinkedList section when I call guest != 0, I'm getting an error Bad Operand. How can I check and print whether my guest is equal to zero or not?
Here is a link-based Stack class.
import java.util.Iterator;
public class LStack<T>
{
private Link top;
private int size;
public LStack()
{
top = null;
size = 0;
}
#Override
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for(Link nav = top; nav != null; nav=nav.getNext())
{
sb.append(nav.getDatum());
if(nav.getNext() != null)
{
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
public void push(T newItem)
{
top = new Link(newItem, top);
size++;
}
public T pop()
{
if(isEmpty())
{
throw new EmptyStackException();
}
size--;
T out = top.getDatum();
top = top.getNext();
return out;
}
public T peek()
{
if(isEmpty())
{
throw new EmptyStackException();
}
return top.getDatum();
}
public void clear()
{
top = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return top == null;
}
public Iterator<T> iterator()
{
return new LStackIterator();
}
/********************aliens*******************/
class LStackIterator implements Iterator<T>
{
private Link current;
public LStackIterator()
{
current = top;
}
public T next()
{
T out = current.getDatum();
current = current.getNext();
return out;
}
public boolean hasNext()
{
return current.getNext() != null;
}
}
public static void main(String[] args)
{
LStack<String> elStack = new LStack<>();
elStack.push("A");
elStack.push("B");
elStack.push("C");
elStack.push("D");
for(String quack: elStack)
{
System.out.println(quack);
}
System.out.printf("The size is %d\n", elStack.size());
System.out.println(elStack);
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack.pop());
System.out.println(elStack);
}
class Link
{
private T datum;
private Link next;
public Link(T datum, Link next)
{
this.datum = datum;
this.next = next;
}
public Link(T datum)
{
this(datum, null);
}
public T getDatum()
{
return datum;
}
public Link getNext()
{
return next;
}
}
}
I then try to run and get this.
$ javac LStack.java
LStack.java:95: error: incompatible types: Object cannot be converted to String
for(String quack: elStack)
^
1 error
What is happening here? Changing the type from String to Object causes it to work, but I am not using any raw types.
You must implement Iterable for "For-Each" loop
public class LStack<T> implements Iterable<T>
I am writing a LinkedList implementation which includes a previous function that returns the position prior to the one passed as an input argument. It should check whether the inputted position is the first one and throw an exception in that case:
#Override
public Position<T> previous (Position<T> p) throws PositionException {
if (this.first(p)) {
throw new PositionException();
}
return this.convert(p).prev;
}
However, the following test is failing because it isn't throwing the expected exception from trying to use the previous function on the first position in the array:
#Test (expected=PositionException.class)
public void gettingPreviousAtFront() {
Position<String> one = list.insertFront("One");
Position<String> two = list.insertFront("Two");
assertTrue(list.first(two));
Position<String> beforeTwo = list.previous(two);
}
There was 1 failure: 1)
gettingPreviousAtFront(hw6.test.LinkedListTest)
java.lang.AssertionError: Expected exception:
exceptions.PositionException at
org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
It is even passing the assertion on line 301 of the test that "two" is first. So how is it possible that the exception is not being thrown by the previous function?
Here is the full linkedlist code:
package hw6;
import exceptions.EmptyException;
import exceptions.PositionException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements List<T> {
private static final class Node<T> implements Position<T> {
// The usual doubly-linked list stuff.
Node<T> next; // reference to the Node after this
Node<T> prev; // reference to the Node before this
T data;
// List that created this node, to validate positions.
List<T> owner;
#Override
public T get() {
return this.data;
}
#Override
public void put(T t) {
this.data = t;
}
}
/** This iterator can be used to create either a forward
iterator, or a backwards one.
*/
private final class ListIterator implements Iterator<T> {
Node<T> current;
boolean forward;
ListIterator(boolean f) {
this.forward = f;
if (this.forward) {
this.current = LinkedList.this.sentinelHead.next;
} else {
this.current = LinkedList.this.sentinelTail.prev;
}
}
#Override
public T next() throws NoSuchElementException {
if (!this.hasNext()) {
throw new NoSuchElementException();
}
T t = this.current.get();
if (this.forward) {
this.current = this.current.next;
} else {
this.current = this.current.prev;
}
return t;
}
#Override
public boolean hasNext() {
if (this.forward) {
return this.current != LinkedList.this.sentinelTail;
}
else {
return this.current != LinkedList.this.sentinelHead;
}
}
}
/* ** LinkedList instance variables are declared here! ** */
private Node<T> sentinelHead;
private Node<T> sentinelTail;
private int length; // how many nodes in the list
/**
* Create an empty list.
*/
public LinkedList() {
this.sentinelHead = new Node<>();
this.sentinelTail = new Node<>();
this.sentinelHead.owner = this;
this.sentinelTail.owner = this;
this.sentinelTail.prev = this.sentinelHead;
this.sentinelHead.next = this.sentinelTail;
this.length = 0;
}
// Convert a position back into a node. Guards against null positions,
// positions from other data structures, and positions that belong to
// other LinkedList objects. That about covers it?
private Node<T> convert(Position<T> p) throws PositionException {
try {
Node<T> n = (Node<T>) p;
if (n.owner != this) {
throw new PositionException();
}
return n;
} catch (NullPointerException | ClassCastException e) {
throw new PositionException();
}
}
#Override
public boolean empty() {
return this.length == 0;
}
#Override
public int length() {
return this.length;
}
#Override
public boolean first(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
return this.sentinelHead.next == n;
}
#Override
public boolean last(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
return this.sentinelTail.prev == n;
}
#Override
public Position<T> front() throws EmptyException {
if (this.length == 0) {
throw new EmptyException();
}
return this.sentinelHead.next;
}
#Override
public Position<T> back() throws EmptyException {
if (this.empty()) {
throw new EmptyException();
}
return this.sentinelTail.prev;
}
#Override
public Position<T> next(Position<T> p) throws PositionException {
if (this.last(p)) {
throw new PositionException();
}
return this.convert(p).next;
}
#Override
public Position<T> previous(Position<T> p) throws PositionException {
if (this.first(p)) {
throw new PositionException();
}
return this.convert(p).prev;
}
#Override
public Position<T> insertFront(T t) {
return this.insertAfter(this.sentinelHead, t);
}
#Override
public Position<T> insertBack(T t) {
return this.insertBefore(this.sentinelTail, t);
}
#Override
public void removeFront() throws EmptyException {
this.remove(this.front());
}
#Override
public void removeBack() throws EmptyException {
this.remove(this.back());
}
#Override
public void remove(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
n.owner = null;
n.prev.next = n.next;
n.next.prev = n.prev;
this.length--;
}
#Override
public Position<T> insertBefore(Position<T> p, T t)
throws PositionException {
Node<T> current = this.convert(p);
Node<T> n = new Node<T>();
n.owner = this;
n.data = t;
n.prev = current.prev;
current.prev.next = n;
n.next = current;
current.prev = n;
this.length++;
return n;
}
#Override
public Position<T> insertAfter(Position<T> p, T t)
throws PositionException {
Node<T> current = this.convert(p);
Node<T> n = new Node<T>();
n.owner = this;
n.data = t;
n.next = current.next;
current.next.prev = n;
n.prev = current;
current.next = n;
this.length++;
return n;
}
#Override
public Iterator<T> forward() {
return new ListIterator(true);
}
#Override
public Iterator<T> backward() {
return new ListIterator(false);
}
#Override
public Iterator<T> iterator() {
return this.forward();
}
#Override
public String toString() {
StringBuilder s = new StringBuilder();
s.append("[");
for (Node<T> n = this.sentinelHead.next; n != this.sentinelTail; n = n.next) {
s.append(n.data);
if (n.next != this.sentinelTail) {
s.append(", ");
}
}
s.append("]");
return s.toString();
}
}
I have LinkedList with test program. As you can see in that program I add some Students to the list. I can delete them. If I choose s1,s2,s3 oraz s4 to delete everything runs well, and my list is printed properly and information about number of elements is proper. But if I delete last element (in this situation - s5) info about number of elements is still correct, but this element is still printed. Why is that so? Where is my mistake?
public class Lista implements List {
private Element head = new Element(null); //wartownik
private int size;
public Lista(){
clear();
}
public void clear(){
head.setNext(null);
size=0;
}
public void add(Object value){
if (head.getNext()==null) head.setNext(new Element(value));
else {
Element last = head.getNext();
//wyszukiwanie ostatniego elementu
while(last.getNext() != null)
last=last.getNext();
// i ustawianie jego referencji next na nowowstawiany Element
last.setNext(new Element(value));}
++size;
}
public Object get(int index) throws IndexOutOfBoundsException{
if(index<0 || index>size) throw new IndexOutOfBoundsException();
Element particular = head.getNext();
for(int i=0; i <= index; i++)
particular = particular.getNext();
return particular.getValue();
}
public boolean delete(Object o){
if(head.getNext() == null) return false;
if(head.getNext().getValue().equals(o)){
head.setNext(head.getNext().getNext());
size--;
return true;
}
Element delete = head.getNext();
while(delete != null && delete.getNext() != null){
if(delete.getNext().getValue().equals(o)){
delete.setNext(delete.getNext().getNext());
size--;
return true;
}
delete = delete.getNext();
}
return false;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
public IteratorListowy iterator() {
return new IteratorListowy();
}
public void wyswietlListe() {
IteratorListowy iterator = iterator();
for (iterator.first(); !iterator.isDone(); iterator.next())
{
System.out.println(iterator.current());
}
System.out.println();
}
public void infoOStanie() {
if (isEmpty()) {
System.out.println("Lista pusta.");
}
else
{
System.out.println("Lista zawiera " + size() + " elementow.");
}
}
private static final class Element{
private Object value;
private Element next; //Referencja do kolejnego obiektu
public Element(Object value){
setValue(value);
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
//ustawia referencję this.next na obiekt next podany w atgumencie
public void setNext(Element next) {
if (next != null)
this.next = next;
}
public Element getNext(){
return next;
}
}
private class IteratorListowy implements Iterator{
private Element current;
public IteratorListowy() {
current = head;
}
public void next() {
current = current.next;
}
public boolean isDone() {
return current == null;
}
public Object current() {
return current.value;
}
public void first() {
current = head.getNext();
}
}
}
test
public class Program {
public static void main(String[] args) {
Lista lista = new Lista();
Iterator iterator = lista.iterator();
Student s1 = new Student("Kowalski", 3523);
Student s2 = new Student("Polański", 45612);
Student s3 = new Student("Karzeł", 8795);
Student s4 = new Student("Pałka", 3218);
Student s5 = new Student("Konowałek", 8432);
Student s6 = new Student("Kłopotek", 6743);
Student s7 = new Student("Ciołek", 14124);
lista.add(s1);
lista.add(s2);
lista.add(s3);
lista.add(s4);
lista.add(s5);
lista.wyswietlListe();
lista.delete(s5);
lista.wyswietlListe();
lista.infoOStanie();
lista.clear();
lista.infoOStanie();
}
}
The problem is that your setNext(Element next) method does not set anything if next == null. And that is the case for the last element of your list.
So when you call delete.setNext(delete.getNext().getNext());, nothing is actually set because delete.getNext().getNext() is null!
Remove the if (next != null) condition in setNext and it will work.
I'm having a problem with trying the logic and trying to write a min and additionMerge function and their recursive versions of the function that takes at least one list as an argument (the first node of the list). This will be a private helper function that is called by a wrapper function that is a member function of the LinkedList class.
public class LinkedList {
private static class ListNode {
public int firstItem;
public ListNode restOfList;
}
private ListNode first;
/**
* Create an empty list.
*/
public LinkedList() {
first = null;
}
public LinkedList(int n) {
first = countDown(n);
}
public LinkedList(String s) {
String[] temp = s.split(",");
for (int i = temp.length-1; i >= 0; i--) {
first = insertAtFront(first, Integer.parseInt(temp[i]));
}
}
public int length() {
return length(first);
}
private static int length(ListNode list) {
if (list == null) {
return 0;
}
int temp = length(list.restOfList);
return temp + 1;
}
public boolean contains(int value) {
return contains(first, value);
}
private static boolean contains(ListNode list, int value) {
if (list == null) {
return false;
}
if (list.firstItem == value) {
return true;
}
return contains(list.restOfList, value);
}
public int sum() {
return sum(first);
}
private static int sum(ListNode list) {
if (list == null) {
return 0;
}
return sum(list.restOfList) + list.firstItem;
}
public int count(int target) {
return count(first, target);
}
private static int count(ListNode list, int target) {
if (list == null) {
return 0;
}
int temp = count(list.restOfList, target);
if (list.firstItem == target) {
temp++;
}
return temp;
}
public void replace(int oldValue, int newValue) {
replace(first, oldValue, newValue);
}
private static void replace(ListNode list, int oldValue, int newValue) {
if (list == null) {
return;
}
replace(list.restOfList, oldValue, newValue);
if (list.firstItem == oldValue) {
list.firstItem = newValue;
}
}
public void insertAtFront(int n) {
first = insertAtFront(first, n);
}
private static ListNode insertAtFront(ListNode list, int n) {
ListNode answer = new ListNode();
answer.firstItem = n;
answer.restOfList = list;
return answer;
}
private static ListNode countDown(int n) {
if (n == 1) {
ListNode answer = new ListNode();
answer.firstItem = 1;
answer.restOfList = null;
return answer;
}
ListNode temp = countDown(n - 1);
ListNode answer = insertAtFront(temp, n);
return answer;
}
public void insertAtBack(int item) {
first = insertAtBack(first, item);
}
private static ListNode insertAtBack(ListNode list, int item) {
if (list == null) {
ListNode answer = new ListNode();
answer.firstItem = item;
answer.restOfList = null;
return answer;
}
//List answer = new ListNode();
//answer.firstItem = list.firstItem;
ListNode temp = insertAtBack(list.restOfList, item);
//answer.restOfList = temp;
list.restOfList = temp;
return list;
}
public void concatenate(LinkedList otherList) {
this.first = concatenate(this.first, otherList.first);
}
private static ListNode concatenate(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
ListNode temp = concatenate(list1.restOfList, list2);
list1.restOfList = temp;
return list1;
}
public void filter(int item) {
first = filter(first, item);
}
#Override
public String toString() {
if (first == null) {
return "";
}
StringBuilder sb = new StringBuilder(256);
sb.append(first.firstItem);
for (ListNode current = first.restOfList;
current != null;
current = current.restOfList) {
sb.append(',');
sb.append(current.firstItem);
}
return sb.toString();
}
private static ListNode filter(ListNode list, int item) {
if (list == null) {
return null;
}
ListNode temp = filter(list.restOfList, item);
if (list.firstItem == item) {
return temp;
}
list.restOfList = temp;
return list;
}
public int min() throws RuntimeException {
if (first == null)
throw new RuntimeException("List is Empty");
else
return min();
}
// * A private recursive helper function that returns the minimum item in a
* list whose first node is the argument list.
private static int min(ListNode list) throws RuntimeException {
if (list == null) {
return 0;
}
}
public void additionMerge(LinkedList l2) {
}
* Every node in the list that begins with node
* node1 is increased by the ammount of the corresponding
* node in the list that begins with node node2.
* If one list is longer than the other, the missing nodes
* in the shorter list are assumed to be 0.
private static ListNode additionMerge(ListNode node1, ListNode node2) {
if (list == null) {
return null;
}
}
}
If this is not homework, then my advice is:
Don't write your own LinkedList class. Use the existing out, and add the extra functionality either as a helper class or by extending the existing class.
If you do decide to implement your own linked list class, then you should beware of using recursion. Recursion gives a neat soltion, but there is a major drawback with recursion in Java. The JVM does not do tail call optimization, so a recusive algorithm that recurses deeply (e.g. recursively traversing a long list) is liable to cause a StackOverflowError.