My Java assignment is to implement a set class by using an array.
The assignment won't allow me import the set class from the library, so I have to make it on my own. When I tried to print out the array, it prints out numbers in repeats, not unique numbers. I don't know where the problem is, so if you guys can find any errors in my code, it would be great. I tried to add numbers 2, 3, and 4 to the set, so the result should be 2 3 4, but the code shows me 2 3 2 3 2.
I think the source of the problem is from the add method from the set class, but I don't know what the problem is exactly.
import java.util.Arrays;
public final class Set implements SetInterface
{
private int[] set;
private int size;
private int capacity;
public Set(int c)
{
capacity = c;
set = new int[capacity];
size = 0;
}
public boolean contains(int x)
{
boolean contains = false;
for(int i = 0; i<capacity; i++)
{
if(x == set[i])
contains = true;
else
contains = false;
}
return contains;
}
public void add(int x)
{
for(int i = 0; i<capacity; i++)
{
if(!contains(x))
{
if(size == capacity)
{
set = Arrays.copyOf(set,size*2);
}
if(set[i]==0)
{
set[i++] = x;
}
}
}
size++;
}
public boolean remove(int x)
{
boolean remove = false;
for(int i = 0; i < capacity; i++)
{
if(x == set[i])
{
set[i] = set[size -1];
size--;
remove = true;
}
if(isEmpty())
{
remove = false;
}
}
return remove;
}
public void clear()
{
set = null;
size = 0;
}
public int size()
{
return size;
}
public boolean isEmpty()
{
if(size == 0)
return true;
else
return false;
}
public int[] toArray()
{
return Arrays.copyOf(set, capacity);
}
}
This is the driver class that I test my class.
import java.util.Arrays;
public class SetDriver
{
public static void main(String[] args)
{
SetDriver driver = new SetDriver();
Set s1 = new Set(5);
s1.add(2);
s1.add(3);
s1.add(4);
driver.print(s1);
System.out.println("Size: "+s1.size());
}
public static void print(Set s)
{
for(int i = 0; i<s.toArray().length; i++)
{
System.out.print(s.toArray()[i]+" ");
}
System.out.println("");
}
}
The outputs are here:
2 3 2 3 2
Size: 3
There's a likely problem with your contains method. Suppose that you did find a duplicate. What happens is that you assign your variable to true and you continue to iterate. This stomps over the logic entirely; you could have a duplicate but never act on it because your boolean code precludes you from doing so.
Ideally, when you find a match, you must stop iterating and return immediately.
public boolean contains(int value) {
for(int setItem : set) {
if(setItem == value) {
return true;
}
}
return false;
}
You should change add method like this.
public void add(int x) {
if (contains(x))
return;
if (size >= capacity) {
capacity *= 2;
set = Arrays.copyOf(set, capacity);
}
set[size++] = x;
}
Related
I was solving a small assignment from the Infytq Learning program, where I come across this hindrance. i can't seem to figure out the problem I'm having.
Given a queue.
I have to form a new queue of whole numbers from the given queue where the numbers in the queue are evenly
divisible by all the numbers from 1 to 10.
Here's what I have done so far. I'm currently getting empty queue.
class Queue {
private int front;
private int rear;
private int maxSize;
private int arr[];
Queue(int maxSize) {
this.front = 0;
this.rear = -1;
this.maxSize = maxSize;
this.arr = new int[this.maxSize];
}
public boolean isFull() {
if (rear == maxSize - 1) {
return true;
}
return false;
}
public boolean enqueue(int data) {
if (isFull()) {
return false;
} else {
arr[++rear] = data;
return true;
}
}
public void display() {
if(isEmpty())
System.out.println("Queue is empty!");
else {
for (int index = front; index <= rear; index++) {
System.out.println(arr[index]);
}
}
}
public boolean isEmpty() {
if (front > rear)
return true;
return false;
}
public int dequeue() {
if (isEmpty()) {
return Integer.MIN_VALUE;
} else {
int data = arr[this.front];
arr[front++] = Integer.MIN_VALUE;
return data;
}
}
public int getMaxSize() {
return maxSize;
}
}
class Tester {
public static void main(String[] args) {
Queue queue = new Queue(7);
queue.enqueue(13983);
queue.enqueue(10080);
queue.enqueue(7113);
queue.enqueue(2520);
queue.enqueue(2500);
Queue outputQueue = findEvenlyDivisibleNumbers(queue);
System.out.println("Evenly divisible numbers");
outputQueue.display();
}
public static Queue findEvenlyDivisibleNumbers(Queue queue) {
//Implement your code here and change the return value accordingly
Queue nqueue = new Queue(queue.getMaxSize());
boolean flag = true;
while(!(queue.isEmpty())){
int val = queue.dequeue();
for(int i=2;i<=10;i++){
if(val%i!=0){
flag=false;
break;
}
}
if(flag){
nqueue.enqueue(val);
}
}
return nqueue;
}
}
You should reset your flag to true before each iteration of your while loop (as you've been suggested already).
In order to avoid such issues, consider extracting the internal loop into a separate method. That will help avoiding nested loop breaking confusion:
public static boolean isDivisible(int value) {
for (int i = 2; i < 10; i++) {
if (value % i > 0) {
return false;
}
}
return true;
}
then simply use it while iterating over your queue:
public static Queue findEvenlyDivisibleNumbers(Queue queue) {
Queue nqueue = new Queue(queue.getMaxSize());
while (!(queue.isEmpty())) {
int value = queue.dequeue();
if (isDivisible(value)) {
nqueue.enqueue(value);
}
}
return nqueue;
}
import java.util.Arrays;
import java.util.Iterator;
public class ArrayList<Type> implements Iterable<Type> {
Type[] arr = (Type[]) new Object[10];
int size = 0;
//change capacity
public void newCapacity(int i) {
if (i == 0) {
int newIncreasedCapacity = arr.length * 2;
arr = Arrays.copyOf(arr, newIncreasedCapacity);
} else if (i == 1) {
int newDecreasedCapacity = arr.length / 2;
arr = Arrays.copyOf(arr, newDecreasedCapacity);
}
}
// add an item
public void add(Type item) {
if (size == arr.length) {
newCapacity(0);
}
arr[size++] = item; //increases size after appending
}
//remove an item
public Type remove(int index) {
if (size <= arr.length / 4) {
newCapacity(1);
}
Type removedItem = (Type) arr[index];
for (int i = index; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
size -= 1;
return removedItem;
}
public int size() {
int count = 0;
for (int i = 0; i < size; i++) {
count += 1;
}
return count;
}
#Override
public Iterator<Type> iterator() {
return new ArrayIterator(arr);
}
class ArrayIterator<Type> implements Iterator<Type> {
private Type[] arrayList;
public ArrayIterator(Type[] newArray) {
arrayList = newArray;
}
// check if next element not null
public boolean hasNext() {
return (arrayList[size + 1] != null);
}
// next element
public Type next() {
if (arrayList[size + 1] != null) {
return (arrayList[size + 1]);
} else {
return null;
}
}
}
// Main Method
public static void main(String[] args) {
ArrayList<Integer> new_arr = new ArrayList<>();
new_arr.add(5);
new_arr.add(7);
new_arr.add(9);
new_arr.remove(0);
System.out.println(new_arr.size());
for (int i : new_arr) {
System.out.println(new_arr.size());
System.out.println(i);
}
}
}
I implemented the code for a custom ArrayList and also implemented an iterator for my custom data type, but I am facing an issue.
So when i run the for each loop in the main method, the loop does not run and thus nothing is printed on the console.I have checked the array which is being used for the for-each loop is not empty.Please help!
I think that you should fix your Iterator to something like
class ArrayIterator<Type> implements Iterator<Type> {
private Type[] arrayList;
private int position;
public ArrayIterator(Type[] newArray) {
arrayList = newArray;
position = 0;
}
// check if next element not null
public boolean hasNext() {
return (position != size);
}
// next element
public Type next() {
if (arrayList[position] != null) {
return (arrayList[position++]);
} else {
return null;
}
}
}
You are using the position of the size of the array to calculate the next() and hasNext(), the hasNext() is always returning null.
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.
I have 3 arrays of 5 items. Inputting an integer that is less than 99 will place it in the first array, inputting an integer from 101 to 199 will put it into the second and 201-299 will put it into the 3rd array.
import java.util.Arrays;
import java.util.Scanner;
public class priorityQueue {
private int[][] queueArray;
}
public priorityQueue() //constructor
{
queueArray = new int[3][5];
}
public void printQueue() {
System.out.println(Arrays.toString(queueArray));
}
public boolean isFull(int[] array){
return (array.length-1 == 5);
}
public boolean enqueue(int item){
//returns true or false if enqueue is not possible
//try lower priority queue(s) if necessary
}
I have no idea how to implement a priority into how integers are inserted, could anyone point me in the right direction?
Here's a rudimentary implementation of the requirements, for what it's worth. Note that you can get your index into the first level of queueArray by using integer division on your item parameter like so: int whichQueue = item / 100;
import java.util.Arrays;
public class PriorityQueue
{
private int[][] queueArray;
public PriorityQueue() // constructor
{
queueArray = new int[3][5];
}
public void printQueue()
{
System.out.println(Arrays.toString(queueArray));
}
public boolean isFull(int[] array)
{
return findEmptySlot(array) < 0;
}
public boolean enqueue(int item)
{
if (item < 1 || item > 299) {
throw new IllegalArgumentException("item must be between 1 and 299");
}
for (int i = item / 100; i < this.queueArray.length; i++) {
if (enqueue(item, this.queueArray[i])) {
return true;
}
}
return false;
}
private boolean enqueue(int item, int[] queue) {
int emptySlot = findEmptySlot(queue);
if (emptySlot >= 0) {
queue[emptySlot] = item;
return true;
}
return false;
}
private int findEmptySlot(int[] queue) {
for (int i = 0; i < queue.length; i++) {
if (queue[i] == 0) {
return i;
}
}
return -1;
}
}
I'm new to Java and I'm having some problems shuffling a list.
I have to write the Iterable class so that when you iterate over the queue it returns the items in a randomly order. That's why I wrote that shuffle method and then I'm calling it inside RandomizedQueueIterator class
import java.util.Iterator;
import java.util.NoSuchElementException;
public class RandomizedQueue<Item> implements Iterable<Item>
{
// instance variables
private Item[] queue;
private int N = 0;
private int R = 0;
// constructor
public RandomizedQueue()
{
queue = (Item[]) new Object[1];
}
// helper functions
private void resize(int capacity)
{
Item[] copy = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++)
copy[i] = queue[i];
queue = copy;
}
private void shrink(int capacity)
{
Item[] copy = (Item[]) new Object[capacity];
int M = 0;
for (int i = 0; i < N; i++)
{
if (queue[i] != null)
copy[M++] = queue[i];
}
queue = copy;
}
// shuffle queue
private void shuffle(Item[] a )
{
int N = a.length;
for (int i = 0; i < N; i++)
{
int r = StdRandom.uniform(i + 1);
Item temp = a[r];
a[r] = a[i];
a[i] = temp;
}
}
// return wether queue is empty
public boolean isEmpty() { return queue.length == 0; }
// return size of queue
public int size() { return queue.length; }
// add item to the queue
public void enqueue(Item item)
{
if (N == queue.length) { resize(N*2); }
queue[N++] = item;
}
// remove and return a random item from the queue
public Item deque()
{
// generate a random index and store item
int random_index;
do {
random_index = StdRandom.uniform(0, N);
} while (queue[random_index] == null);
Item item = queue[random_index];
// delete item from array and increment counter of null items
queue[random_index] = null;
R += 1;
// shrink array if corresponds
if (R == (3/4 * N)) { shrink(N/2); }
// return item
return item;
}
// return a random item from the queue
public Item sample()
{
// generate a random index and store item
int random_index;
do {
random_index = StdRandom.uniform(0, N);
} while (queue[random_index] == null);
Item item = queue[random_index];
// return item
return item;
}
// iteration
public Iterator<Item> iterator()
{
return new RandomizedQueueIterator();
}
private class RandomizedQueueIterator implements Iterator<Item>
{
private int i = 0;
shuffle(queue);
public boolean hasNext()
{
return i < N;
}
public Item next()
{
if (i >= N)
{
throw java.util.NoSuchElementException;
}
return queue[i++];
}
public void remove()
{
throw new UnsupportedOperationException("Invalid operation for array");
}
}
// main method
public static void main(String[] args)
{
RandomizedQueue example = new RandomizedQueue();
example.enqueue(0);
example.enqueue(1);
example.enqueue(2);
example.enqueue(3);
example.enqueue(3);
example.enqueue(3);
example.enqueue(3);
}
}
The output when trying to compile:
2 errors found:
[line: 114] Error: invalid method declaration; return type required
[line: 114] Error: expected
line:114 > shuffle(queue);
Any help would be really appreciated.
Thanks
If you want to run the class you need to put the method call in a main method
public static void main(String...args) {
shuffle(list_test);
}
If you do this you will either define list_test as a static variable or define it inside the main method.
There are a couple of problems. One of the problems is that you are calling the function method "inside" your class not in a function. You should be calling the function outside after you have create the test object.
So In your main. Call:
list_test = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
test testObj = new test();
newList = test.shuffle(list_test); // in the case it returns a new list
where
private void shuffle(int[] a )
// and returns a new list
return shuffled_list
If you only care about shuffling items in your list, use the JDK built-in shuffle() method instead.
There are quite a few things that can be improved. Your class might look like this:
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Random;
// it is standard to use E or T for collections
public class RandomizedQueue<E> implements Iterable<E> {
// most java collections have a default size of 16, set at 2 for testing
private static final int DEFAULT_INITIAL_CAPACITY = 2;
private static final Random GENERATOR = new Random();
// have good variable names
private boolean iterating = false; // to avoid concurrent modification
private E[] queue;
private int size = 0;
#SuppressWarnings("unchecked")
public RandomizedQueue() {
queue = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
// remove and return a random item from the queue
public E dequeue() {
if (iterating) {
throw new ConcurrentModificationException();
}
return dequeue(GENERATOR.nextInt(size));
}
// add item to queue
public void enqueue(E item) {
if (iterating) {
throw new ConcurrentModificationException();
}
if (size == queue.length) {
resize(size * 2);
}
queue[size++] = item;
}
// return whether queue is empty
public boolean isEmpty() {
return size == 0;
}
// iteration
public Iterator<E> iterator() {
return new RandomizedQueueIterator();
}
// return a random item from the queue
public E sample() {
if (isEmpty()) {
throw new NoSuchElementException("trying to sample from empty queue");
}
return queue[GENERATOR.nextInt(size)];
}
// shuffle queue
public void shuffle() {
for (int i = size - 1; i >= 0; i--) {
swap(i, GENERATOR.nextInt(i + 1));
}
}
// return size of queue
public int size() {
return size;
}
// helper functions
private E dequeue(int randomIndex) {
if (isEmpty()) {
throw new NoSuchElementException("trying to remove from empty queue");
}
size--;
// resize if only 1/4 of the queue is full
if (size < queue.length / 4) {
resize(queue.length / 2);
}
// since all get data methods are random, only need to swap on remove
swap(randomIndex, size);
E randomItem = queue[size];
queue[size] = null;
return randomItem;
}
private void resize(int capacity) {
// copyOf is substantially faster since it uses arraycopy which is in native code
queue = Arrays.copyOf(queue, capacity);
}
// swap data at indices i and j
private void swap(int i, int j) {
E temp = queue[j];
queue[j] = queue[i];
queue[i] = temp;
}
private class RandomizedQueueIterator implements Iterator<E> {
private int currentIndex = 0;
private int indexToRemove = -1;
private RandomizedQueueIterator() {
iterating = true;
shuffle();
}
public boolean hasNext() {
return currentIndex < size;
}
public E next() {
if (currentIndex >= size) {
throw new NoSuchElementException();
}
indexToRemove = currentIndex;
E nextElement = queue[currentIndex++];
if (currentIndex == size) {
iterating = false;
}
return nextElement;
}
public void remove() {
if (indexToRemove == -1) {
throw new IllegalStateException();
}
// print for testing
System.out.println("r: " + dequeue(indexToRemove));
currentIndex--;
indexToRemove = -1;
}
}
// main method
public static void main(String[] args) {
int exampleSize = 7;
System.out.println("example 1:");
RandomizedQueue<Integer> example1 = new RandomizedQueue<>();
for (int i = 0; i < exampleSize; i++) {
example1.enqueue(i);
}
System.out.println("size: " + example1.size());
for (int i = 0; i < exampleSize; i++) {
System.out.println("d: " + example1.dequeue());
}
System.out.println("size: " + example1.size());
System.out.println("\nexample 2:");
RandomizedQueue<Integer> example2 = new RandomizedQueue<>();
for (int i = 0; i < exampleSize; i++) {
example2.enqueue(i);
}
System.out.println("size: " + example2.size());
Iterator<Integer> iterator = example2.iterator();
// iterator.remove(); throws IllegalStateException
while (iterator.hasNext()) {
System.out.println("i: " + iterator.next());
iterator.remove();
System.out.println("size: " + example2.size());
// iterator.remove(); should throws IllegalStateException
}
}
}
Use this to give you ideas on how to write your class.