Queue modulus in en-queue and de-queue method? - java

So I have this code I need to analyze and learn from it, about how bounded queue works, here it is:
class Queue<T> { // bounded
private T[] seq; // the sequence
private int size = 0; // size of sequence
private int head = 0; private int tail = 0; // front and rear
Queue(int n) { // n>0
seq = (T[])(new Object[n]);
}
Queue(){ this(10000);} // = seq=(T[])(new Object[10000]);
boolean isEmpty() { return size==0;}
boolean enq(T t) {
if (size<seq.length) {
seq[tail] = t; tail = (tail+1)%seq.length; size++;
return true;
}
else return false;
}
T deq() {
if (isEmpty()) return null;
else {
T temp = seq[head];
head = (head+1)%seq.length; size--;
return temp;
}
}
}
So everything is okay, but I don't understand why in the name of god is there a modulus (%) operation in the enq(T t) method and deq() method...

There is a modulus operation so that the queue can be represented by an array, where the contents of the queue "wrap around" the end of the array to the beginning.
Example with a size of 10:
[6th] [tail] [empty] [empty] [empty] [head] [2nd] [3rd] [4th] [5th]
Here, head = 5, and tail = 1, because a total of 12 items have been added and 5 removed. Even if there isn't enough room at the end of the array, there is room at the beginning of the array to store more data up until the capacity of the array.
The modulus operations allow the head and tail to wrap around on a deq and enq operation, respectively, so that 9 becomes 0 instead of 10, which would have caused an ArrayIndexOutOfBoundsException.

Related

How to use Iterator next() method to generate power set of LinkedSet

For my class I have to create an iterator that will generate a power set of a LinkedSet. Per my professor, I have to iterate through a bitString of the int current. Where current is the subset to which we are adding elements of the main set. I keep having a NullPointerException. I think I am looping through the bitString correctly but when I want to move to the next node in the set, it is saying it is null. I've stared at this for 12 hours and cannot figure out what to do. My professor provided a framework, so I'll explain what is mine and what is his.
This is the framework:
private class LinkedSetPowerSetIterator implements Iterator<Set<T>> {
// cardinality of this set
int N;
// cardinality of the power set (2^N)
int M;
// the integer identifier of the current subset, i.e. the current element
// of the power set. Legal values range from 0..M-1 inclusive.
int current;
public LinkedSetPowerSetIteratorInt32BitString() {
// initialize N, M, and current here
}
public boolean hasNext() {
return current < M;
}
public Set<T> next() {
LinkedSet<T> s = new LinkedSet<T>();
char[] bitstring = Integer.toBinaryString(current).toCharArray();
// iterate from right to left over bitstring and the internal
// linked list to ensure that the call to add will insert a new
// first node (constant time)
current = current + 1;
return s;
}
public void remove() {
}
}
What I have so far:
private class myPowerIterator implements Iterator<Set<T>> {
// cardinality of set
int N;
// cardinality of power set (2^N)
int M;
//current subset in power set
int current;
// starting node, rear node
Node set = rear;
public myPowerIterator() {
N = size;
M = (int)Math.pow(2, N);
current = 0;
}
public boolean hasNext() {
return (current < M);
}
public Set<T> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
LinkedSet<T> result = new LinkedSet<T>();
char[] bitString = Integer.toBinaryString(current).toCharArray();
for (int i = bitString.length - 1; i >= 0; i--) {
if (bitString[i] == 1) {
result.add(set.element); // How do I make sure it is adding elements
set = set.prev; // from starting set? Keep getting Error:
} // NullPointerException: Cannot read field
else { // "prev" because this.set is null.
set = set.prev;
}
}
current = current + 1;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
You need to implement the Iterable<T> interface in your LinkedSet<T>. If you don't do this then your next() method will not "reset" it's location, thus giving you the NullPointer.

Implement Queue using fixed size array

I came across below interview question and I am working on it:
Build a queue class with the enqueue and dequeue methods. The queue
can store an UNLIMITED number of elements but you are limited to
using arrays that can store up to 5 elements max..
Here is what I was able to come up with. Is this the right way to do it in the interview or is there any better way we should implement in the interview?
class Solution {
private final List<List<Integer>> array;
public Solution() {
this.array = new ArrayList<>();
}
public void enqueue(int value) {
if(array.isEmpty()) {
List<Integer> arr = new ArrayList<>();
arr.add(value);
array.add(arr);
return;
}
if(array.get(array.size() - 1).size() != 5) {
array.get(array.size() - 1).add(value);
return;
}
List<Integer> arr = new ArrayList<>();
arr.add(value);
array.add(arr);
return;
}
public int dequeue() {
if(array.isEmpty()) {
return -1;
}
for(List<Integer> l : array) {
for(int i=0; i<l.size(); i++) {
return l.remove(i);
}
}
return -1;
}
}
As I mentioned in comments, your solution doesn't really solve the problem because the outer array of 5-element arrays can have more than 5 elements.
Instead, you can implement the queue as a linked list of 4-integer nodes, using the 5th element for a reference to the next array. But there's no reason to assume the elements are integers. This turns out to be pretty simple.
public class SillyQueue<T> {
private static final int MAX = 5;
private Object [] head = new Object[MAX], tail = head;
private int headPtr = 0, tailPtr = 0;
void enqueue(T x) {
if (tailPtr == MAX - 1) {
Object [] a = new Object[MAX];
tail[MAX - 1] = a;
tail = a;
tailPtr = 0;
}
tail[tailPtr++] = x;
}
T dequeue() {
if (headPtr == MAX - 1) {
head = (Object[]) head[MAX - 1];
headPtr = 0;
}
return (T) head[headPtr++];
}
}
Your answer uses ArrayList instead of true arrays, and worse, uses an unlimited arraylist to put those arrays in. I think that the interviewers expected you to implement a singly-linked list of 5-element arrays:
/**
* A singly-linked list node with an array; supports popping its 1st elements,
* and adding elements at the end, possibly by creating a new node
*/
public class ListNode {
final int MAX = 5;
private int contents[] = new int[MAX];
private int size = 0; // valid elements
private ListNode next = null;
private ListNode(ListNode next) {
this.next = next;
}
public boolean isEmpty() { return size == 0; }
public ListNode addLast(int value) {
ListNode next = this;
if (size == MAX) {
next = new ListNode(this);
}
next.contents[next.size ++] = value;
return next;
}
public int removeFirst() {
if (size == 0) {
throw new NoSuchElementException("empty queue");
}
int value = contents[0];
size --;
for (int i=1; i<size; i++) contents[i-1] = contents[i];
return value;
}
}
/**
* A simple queue on top of nodes that keep arrays of elements
*/
public class ListArrayQueue {
ListNode first = new ListNode();
ListNode last = first;
public void enqueue(int value) {
last = last.addLast(value);
}
public int dequeue() {
if (first.isEmpty() && first != last) {
first = first.next;
}
return first.removeFirst();
}
}
Performance-wise, this can be improved: you can avoid keeping the size in each ListNode, since only the 1st and last nodes can be non-full. You can also avoid the loop in removeFirst, but that would entail replacing size by firstIndex and lastIndex; which could again be moved into the ListArrayQueue to save space in each node.
If they has asked you to build an unlimited array out of 5-element array pieces, you would have had to implement something similar to a b-tree. Which, without handy references, would be quite hard to pull off during an interview.
You can use a 1-D array and use Wrap-around indexing to implement the queue with the limitation that queue can contain maximum 5 elements.
For checking the condition of empty queue, maintain a variable that counts the number of elements present in the queue.
Is this the right way to do it in the interview…?
Presenting uncommented code is never right, let alone in an interview.
In an interactive interview, it would be your task to find out whether you can/should use an unlimited number of arrays.
If not, you have to negotiate a way to handle an enqueue() to a queue filled to capacity in addition to a dequeue() to an empty one.
Fix the type of items the queue can hold.
Agree upon the parameters of the enqueue and dequeue methods.
The task is to Build a queue class, Solution is a bad choice for a name - array for something to access the items is no better.
In a language providing arrays, I'd take limited to using arrays literally - if using something more, why not an implementation of java.util.Queue?
The empty queue handling is entirely redundant: in enqueue(), you could have used
if (!array.isEmpty() && array.get(array.size() - 1).size() < 5); in dequeue() you can just drop it.
Instantiating List<Integer>s, you know there won't be more than five items at a time: tell the constructor.
dequeue() leaves empty List<Integer>s in arrays, giving rise to the current nested loop that desperately needs a comment.
(For the second part of the question, I second Rajkamal Tomar.)
Trade Off - Organize Fixed Size Arrays
Manage arrays based on ArrayList
enqueue - append new fixed size array - O(1)
dequeue - remove first fixed size array - O(n)
Manage arrays based on LinkedList
enqueue - append new fixed size array to linked list - O(1)
dequeue - remove first fixed size array - O(1)
cons - extra next pointer to setup linked list
public class FixedArrayQueue<T> {
private Node<T> head, tail;
private int front, rear, size;
private final int SIZE;
public FixedArrayQueue(int n) {
SIZE = n;
head = tail = new Node<T>(SIZE);
front = rear = size = 0;
}
public void enqueue(T t) {
tail.array[rear++] = t;
if (rear == SIZE) {
rear = 0;
append();
}
size++;
}
public T dequeue() {
if (size == 0) {
throw new EmptyQueueException();
}
T ret = head.array[front++];
if (front == SIZE) {
front = 0;
remove();
}
size--;
return ret;
}
private void append() {
tail.next = new Node<T>(SIZE);
tail = tail.next;
}
private void remove() {
head = head.next;
}
private boolean isEmpty() {
return size == 0;
}
private int size() {
return size;
}
}
class Node<T> {
T[] array;
Node<T> next;
public Node(int n) {
array = (T[]) new Object[n];
}
}

Iterate through a 2D array as if it were a 1D array using Iterator

I'm a beginner in Java and I have to recieve values from such thing as Iterator<Iterator<Integer>>. For example, we may have:
{{1, 2}, {3, 4}, {5, 6}}
The result of next() should be 1. If we try next() one more time - 2, then - 3, 4, etc. Like getting values from 1D array one by one, but from 2D array. We should not copy anything. So, I wrote some bad code below:
public class IteratorNext {
private Iterator<Iterator<Integer>> values = null;
private Iterator<Integer> current;
public IteratorNext(Iterator<Iterator<Integer>> iterator) {
this.values = iterator;
}
public int next() throws NoSuchElementException {
current = values.next();
if (!current.hasNext()) {
values.next();
}
if (!values.hasNext() && !current.hasNext()) {
throw new NoSuchElementException("Reached end");
}
return current.next();
}
}
That code is not correct, because result of next() is 1, then 3, then 5 and because of exception here. How to fix this?
If you are using Java-8, you can take advantage of the flatMapToInt function to iron out your 2D array into a 1D array (array2d can be assumed to be a reference to your 2D array) :
Arrays.stream(array2d).flatMapToInt(Arrays::stream).forEach(System.out::println);
if you want to stick to your solution, you need to modify your next method as follows :
public int next() throws NoSuchElementException {
int result = -1;
//Are we already iterating one of the second dimensions?
if(current!=null && current.hasNext()) {
//get the next element from the second dimension.
result = current.next();
} else if(values != null && values.hasNext()) {
//get the next second dimension
current = values.next();
if (current.hasNext()) {
//get the next element from the second dimension
result = current.next();
}
} else {
//we have iterated all the second dimensions
throw new NoSuchElementException("Reached end");
}
return result;
}
public static class IteratorNext {
private Iterator<Iterator<Integer>> values = null;
private Iterator<Integer> current;
public IteratorNext(Iterator<Iterator<Integer>> iterator) {
this.values = iterator;
}
public int next() throws NoSuchElementException {
if (current != null && current.hasNext()) {
Integer val = current.next();
return val;
}
if (values != null && values.hasNext()) {
current = values.next();
if (current != null && current.hasNext()) {
Integer val = current.next();
return val;
}
}
throw new NoSuchElementException("Reached end");
}
}
Each time you call next(), you have to deal with the result.
The first line of your next() method you skip the first element because you recall current.next() at the end of your next() method.
More generally speaking this code is not the right way to deal with collections. You have to analyze the problem in term of usage.
The problem is that each time you call next() you start with
current = values.next();
So at each call you skip to the next iterator, without trying to continue iteration on current.
Instead you should do something like
if(!current.hasNext())
current = values.next();

Adding a value at an index in an array list

I need to make my own data structures and part of this is doing an ArrayList. I need to make sure I can add an object at element n while pushing all the others down. Here is my code. Right now it is adding the element twice. It is the function public ReturnObject add(int index, Object item). I need this function to add the object at the specified index and then shift the others down.
public class ArrayList implements List{
public static final int CAPACITY=16;
private int size = 0;
private Object[] data;
ReturnObjectImpl ro;
//constructors
public ArrayList() {
data = new Object[CAPACITY];
} //CONSTRUCTS LIST WITH DEFAULT CAPACITY
public ArrayList(int capacity) { // constructs list with given capacity
data = new Object[capacity];
System.out.println("Created an ArrayList of capacity " + capacity);
}
public boolean isEmpty(){
if(size == 0) {
// System.out.println("The list is empty");
return true;
}
return false;
}
public int size(){
System.out.println("The ArrayList is not full, but currently has " + size + " indexs");
return size;
}
public ReturnObject get(int index){
ro = new ReturnObjectImpl(data[index]);
return ro;
}
public ReturnObject remove(int index){
return null;
}
public ReturnObject add(int index, Object item){
if(index <= size && index < data.length){
for (int x = size-1; x >= index; x--){
data[x+1] = data[x];
data[index] = item;
ro = new ReturnObjectImpl(data[index]);
size++;
}
System.out.println("Added to array at " + index);
}
return ro;
}
public ReturnObject add(Object item){
if (data[0] == null){
data[0] = item;
}
//int adding = size + 1;
data[size] = item;
System.out.println("Added item to index " + size);
size++;
return null;
}
//added - but DELETE BEFORE SUBMITTING
public void printAll(){
for(int x = 0; x < data.length; x++){
System.out.println(data[x]);
}
}
}
Obviously, when inserting an object into that array:
for (int x = size-1; x >= index; x--){
data[x+1] = data[x];
data[index] = item;
that should not happen within a loop! Insertion should happen exactly once, at the correct index! So even when you keep that loop to move the other elements, that last assignment should go after that "moving loop" is over.
So the point is: you should step back and carefully look what this loop is doing with its loop variable.
In other words: either take a piece of paper and "run" the code yourself; or run it in a debugger.
As this is probably some kind of homework activity, I will leave it with that; it should be really enough to get you going and help you fix your code.
In addition to GhostCat's answer, instead of a for loop, you can just use System.arrayCopy() to 'move' the right part to the right. You only need to know whether your internal array (data) is already full or not. If it is, then you must expand the internal array.
System.arraycopy(this.data, insertIndex, this.data, insertIndex + 1, 1);
Some notes:
The code
if (data[0] == null) {
data[0] = item;
}
will throw an ArrayIndexOutOfBoundsException if ArrayList(0) was called.
The code
if (size == 0) {
// System.out.println("The list is empty");
return true;
}
return false;
can be rewritten to
return (size == 0);
You seem to omit more checks, like the check whether the internal array is full or not. Your current code does not expand the internal array, so if one ever adds more objects than the initial capacity (default 16), then an ArrayIndexOutOfBoundsException is thrown.

How to fill an array with node elements from a binary search tree, in ascending order?

In a school assignment I'm supposed to complete a method that should return an array of
node elements in ascendig order. The nodes are assembled in a binary search tree, so to sort them correct, I got a tip to create a recursive method to do the job.
The problem is that this doesn't even yield all the elements in the collection according to the test output (java.lang.AssertionError: toArray() does not return all the elements in the collection.)
I couldn't come up with any other way to deal with the array, and I'm not quite sure if the recursion even works. Any help is much appreciated.
Below is my code:
public class BinarySearchTree<E extends Comparable<E>> implements
IfiCollection<E> {
Node root;
Node current;
int size = 0;
int i = 0;
public class Node {
E obj;
Node left, right;
public Node(E e) {
obj = e;
}
} // END class Node
[...]
public E[] toArray(E[] a) {
Node n = root;
a = sort(n, a);
return a;
}
public E[] sort(Node n, E[] a) { //, int idx, E[] a) {
if (n.left != null) {
current = n.left;
sort(current, a);
}
a[i] = current.obj;
i++;
if (n.right != null) {
current = n.right;
sort(current, a);
}
return a;
} // END public Node sort
[...]
} // END class BinarySearchTree
Test output:
java.lang.AssertionError: toArray() does not return all the elements in the collection.: TestPerson("Bender").compareTo(TestPerson("Fry")) == 0 expected:true but was:false
at inf1010.assignment.IfiCollectionTest.assertCompareToEquals(IfiCollectionTest.java:74)
at inf1010.assignment.IfiCollectionTest.assertCompareToEquals(IfiCollectionTest.java:83)
at inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder(IfiCollectionTest.java:100)
at inf1010.assignment.IfiCollectionTest.toArray(IfiCollectionTest.java:202)
protected void assertCompareToEquals(TestPerson actual,
TestPerson expected, String msg) {
assertTrue(actual.compareTo(expected) == 0, String.format( // l:74
"%s: %s.compareTo(%s) == 0", msg, actual, expected));
}
[...]
protected void assertCompareToEquals(TestPerson[] actual,
TestPerson[] expected, String msg) {
for (int i = 0; i < actual.length; i++) {
TestPerson a = actual[i];
TestPerson e = expected[i];
assertCompareToEquals(a, e, msg); // l:83
}
}
[...]
protected void assertCompareToEqualsNoOrder(TestPerson[] actual,
TestPerson[] expected, String msg) {
assertEquals(actual.length, expected.length, msg);
TestPerson[] actualElements = new TestPerson[actual.length];
System.arraycopy(actual, 0, actualElements, 0, actual.length);
TestPerson[] expectedElements = new TestPerson[expected.length];
System.arraycopy(expected, 0, expectedElements, 0, expected.length);
Arrays.sort(expectedElements);
Arrays.sort(actualElements);
assertCompareToEquals(actualElements, expectedElements, msg); // l:100
}
[...]
#Test(dependsOnGroups = { "collection-core" },
description="Tests if method toArray yields all the elements inserted in the collection in sorted order with smallest item first.")
public void toArray() {
TestPerson[] actualElements = c.toArray(new TestPerson[c.size()]);
for (int i = 0; i < actualElements.length; i++) {
assertNotNull(actualElements[i],
"toArray() - array element at index " + i + " is null");
}
TestPerson[] expectedElements = allElementsAsArray();
assertCompareToEqualsNoOrder(actualElements, expectedElements, // l:202
"toArray() does not return all the elements in the collection.");
Arrays.sort(expectedElements);
assertCompareToEquals(actualElements, expectedElements,
"toArray() does not return the elements in sorted order with "
+ "the smallest elements first.");
TestPerson[] inArr = new TestPerson[NAMES.length + 1];
inArr[NAMES.length] = new TestPerson("TEMP");
actualElements = c.toArray(inArr);
assertNull(actualElements[NAMES.length],
"The the element in the array immediately following the "
+ "end of the list is not set to null");
}
I don't know if I should post more of the test code, it's quite extensive, and it might be a little too much for one post?
Ok, I think the problem is your use of the "global" variable current. The way it is set, doesn't make much sense. You don't need to anyway, because the "current" Node is the one that is provided in the parameters.
Also you should consider renaming your function. You aren't sorting anything here, just collecting the contents of the tree, so a name such as collect would be more suitable.
public E[] toArray(E[] a) {
Node n = root;
a = collect(n, a);
return a;
}
public E[] collect(Node n, E[] a) {
if (n.left != null) {
// If there is a left (smaller) value, we go there first
collect(n.left, a);
}
// Once we've got all left (smaller) values we can
// collect the value of out current Node.
a[i] = n.obj;
i++;
if (n.right != null) {
// And if there is a right (larger) value we get it next
collect(n.right, a);
}
return a;
}
(Disclaimer: I haven't tested this)
Alternative implementation without the global index:
public E[] toArray(E[] a) {
Node n = root;
collect(n, a, 0);
return a;
}
public int collect(Node n, E[] a, int i) {
if (n.left != null) {
// If there is a left (smaller) value, we go there first
i = collect(n.left, a, i);
}
// Once we've got all left (smaller) values we can
// collect the value of out current Node.
a[i] = n.obj;
i++;
if (n.right != null) {
// And if there is a right (larger) value we get it next
i = collect(n.right, a, i);
}
return i;
}
I see you have the code
if (n.left != null) {
current = n.left;
sort(current, a);
}
but I can't seem to find at which point you set current back at the current node so that when you do
a[i] = current.obj;
you get the correct result. That's probably why you're not getting all the results. In any case I don't see (at least from the code fragments you have posted) why current needs to be a class variable and not just declared in the sort method. In general you shouldn't be using class variables if you don't really need them.
Edit:
You can either set current back to the node you are processing after calling sort on the left child like this
current = n;
a[i] = current.obj;
i++;
Or not use current at all in which case you'd have something like
if (n.left != null)
sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
sort(n.right, a);
I think where you are confused is that if you check out how a binary search tree works, is that it is always sorted. You start at your root node, and then as you insert a new node, it inserts it into the appropriate position (i.e. to the left or the right) depending on the values. So you should not have to call sort to begin with. So I would start there, and read up on binary search trees. For example wikipedia has a decent article.
Update: Ignore my comment you should not need to do that either. Say you insert 8, 3, 7, 9, 12, 2, 10, 1 into the tree in that order. It should end up looking like this:
8
/ \
3 9
/ \ \
2 7 12
/ /
1 10
If you look at it that means to get them in order, start at the root, then if it has a node to the left got to the left, if not, return itself, and go to the right if it has a value. Repeating this for each node you encounter.
http://cs.armstrong.edu/liang/intro8e/html/BinaryTree.html
The easiest way to do what you are looking for is to traverse the tree inorder and append to an ArrayList. To get the array you can call the .toArray() method of the arrayList.
If you can't use an arraylist, declare an index and an array outside the inordertraversal and increment, you will need to know how many elements are in the tree to declare your array.
pseudo code:
variables:
arraysize = root.count()
E[] inOrderNodeArray = new E[arraysize]
int index = 0
inorder traversal:
void inorder(Node n) {
if (n) {
inorder(n.left)
inOrderNodeArray[index] = n
index++
inorder(n.right)
}
}

Categories