How can I avoid java.lang.ArrayIndexOutOfBoundsException when joining a Queue? - java

I'm working on a simple(?) exercise for my Data Structures class. It works fine right up until I have an element leave the queue then try to add another one on at which point I get the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
at queueExercise.IntegerQueue.join(IntegerQueue.java:20)
at queueExercise.IntegerQueueTest.main(IntegerQueueTest.java:27)
My code is as follows:
Queue Constructor Class:
public class IntegerQueue {
private int[] queue;
private int front;
private int end;
private int noInQueue;
private int count;
private boolean full;
public IntegerQueue(int max) {
queue = new int[max];
front = end = 0;
full = false;
}
public void join(int newValue) {
if (isFull()==false) {
queue[end] = newValue;
count++;
if (end == queue.length) {
end = 0;
}
else {
end++;
}
}else
System.out.println("Error: Queue Full");
}
public int leave() {
if (isEmpty()==false) {
noInQueue = queue[front];
queue[front]=0;
front++;
if (front==queue.length) {
front = 0;
}
count--;
}
else {
System.out.println("Error: Queue Empty");
}
System.out.println("Leaving: "+noInQueue);
return noInQueue;
}
public boolean isEmpty() {
if (count == 0){
return true;
}
else
return false;
}
public boolean isFull() {
if (count >= queue.length) {
return true;
}
else
return false;
}
public void printQueue() {
if (!isEmpty()) {
System.out.println("Printing Queue");
int pos = front;
int i =0;
while(i<queue.length) {
System.out.println(queue[pos]);
pos++;
i++;
if (pos >=queue.length) {
pos = 0;
}
}
}
}
}
Test Class
public class IntegerQueueTest {
static IntegerQueue q = new IntegerQueue(10);
public static void main(String[] args) {
int j;
System.out.println("Creating Queue");
for (int i = 0; i <10; i++) {
j = (int)(Math.random()*100);
if (!q.isFull()) {
q.join(j);
System.out.println("Adding: "+j);
}
}
q.printQueue();
q.join(112);
q.leave();
q.leave();
q.leave();
q.printQueue();
q.join(112);
q.join(254);
q.printQueue();
}
}

The problem is in the join method and more precisely in the condition if (end == queue.length). All you have to do is change it to if (end == queue.length - 1).

Related

Can I add elements to a java queue using array without defining the front and the rear? I am having trouble with this

I am having trouble using enqueue and dequeue functions. I want to add elements without defining the front and rear in my scope.
public class MyStaticQueue
{
private int items[] ;
private int noOfItems = 0;
private int maxItems;
public MyStaticQueue(int m)
{
this.maxItems = m;
this.items = new int[maxItems];
this.noOfItems = 0;
}
public boolean isEmpty()
{
if(noOfItems == 0)
{
return true;
}
else
{
return false;
}
}
public int first()
{
return items[0];
}
public void add(int item)
{
for (int i=0; i<items[maxItems]; i++)
{
if (items[i] == 0)
{
items[i] = item;
}
noOfItems++;
}
}
}

StackOverFlowError when looping through options

I'm working on an exercise and I'm running into something. The following code gives me a stackoverflow error, but I have no idea why because my code should stop.
class Options {
private int amount;
private ArrayList<Integer> pieces;
public void execute() {
pieces = new ArrayList<Integer>();
pieces.add(5);
pieces.add(2);
pieces.add(3);
amount = pieces.size();
combinations(new StringBuilder());
}
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
return;
}
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
It only prints the first output (555).
Thanks.
Add a return to end your recursion
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
return; // <-- like so.
}
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
or put the loop in an else like
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
} else {
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
Edit
static class Options {
private List<Integer> pieces;
public void execute() {
pieces = new ArrayList<>();
pieces.add(5);
pieces.add(2);
pieces.add(3);
combinations(new StringBuilder());
}
public void combinations(StringBuilder current) {
if (current.length() == pieces.size()) {
System.out.println(current.toString());
} else {
for (int i = current.length(); i < pieces.size(); i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
}
public static void main(String[] args) {
Options o = new Options();
o.execute();
System.out.println(o.pieces);
}
Output is
523
[5, 2, 3]

mostFrequent method bags adt(abstract data types)

I am trying to implement a method named mostFrequent in a bag that finds the most frequent object in a bag For example, if B = {Bob, Joe, Bob, Ned, Bob, Bob}, then the method
returns Bob. Hint: The method is O(n^2).
public E MostFrequent (Bag<E> B){
// implementation here
}
The adt of the bag is the following:
package edu.uprm.ece.icom4035.bag;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class StaticBag implements Bag {
private int currentSize;
private Object elements[];
private class BagIterator implements Iterator {
private int currentPosition;
public BagIterator(){
this.currentPosition = 0;
}
#Override
public boolean hasNext() {
return this.currentPosition < currentSize;
}
#Override
public Object next() {
if (hasNext()){
return elements[this.currentPosition++];
}
else {
throw new NoSuchElementException();
}
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public StaticBag(int maxSize){
if (maxSize < 1){
throw new IllegalArgumentException("Max size must be at least 1.");
}
this.currentSize = 0;
this.elements = new Object[maxSize];
}
#Override
public void add(Object obj) {
if (obj == null){
throw new IllegalArgumentException("Value cannot be null.");
}
else if (this.size() == this.elements.length){
throw new IllegalStateException("Bag is full.");
}
else {
this.elements[this.currentSize++] = obj;
}
}
#Override
public boolean erase(Object obj) {
int target = -1;
for (int i=0; i < this.size(); ++i){
if (this.elements[i].equals(obj)){
target = i;
break;
}
}
if (target == -1){
return false;
}
else {
this.elements[target] = this.elements[this.currentSize-1];
this.elements[this.currentSize-1] = null;
this.currentSize--;
return true;
}
}
#Override
public int eraseAll(Object obj) {
int copies = 0;
while(this.erase(obj)){
copies++;
}
return copies;
}
#Override
public int count(Object obj) {
int counter = 0;
for (int i=0; i < this.size(); ++i){
if (elements[i].equals(obj)){
counter++;
}
}
return counter;
}
#Override
public void clear() {
for (int i=0; i < this.size(); ++i){
this.elements[i] = null;
}
this.currentSize = 0;
}
#Override
public boolean isEmpty() {
return this.size() == 0;
}
#Override
public int size() {
return this.currentSize;
}
#Override
public boolean isMember(Object obj) {
return this.count(obj) > 0;
}
#Override
public Iterator iterator() {
return new BagIterator();
}
}
the method must be implemented in the most efficient way and if possible using the methods already given in the bag adt
What I've been trying is the following:
public E MostFrequent(Bag<E> B){
for(E e : B){
int counter = B.count(e)
}
}
but I don't seem to think of a way to return the object with more frequencies inside the loop

How to check diagonals in NQueens?

Im making the NQueens program in java but I am having trouble checking the diagonals. Right now I just go through the array in a way so it goes to the next diagonal spot but it is giving me out of bounds after going through the first possibility. Is there a different way to do this? Am i doing it wrong?
Here is the part that is giving me the array out of bounds exception
private boolean checkLowerDiag(int row, int col)
{
if(col == 0)
{
return false;
}
else
{
for(int i = row, j = col; i < myNumsQueen && j >= 0; i++, j--)
{
if(myBoard[i+1][j-1] == true) // this line is the out of bounds
{
return true;
}
}
return false;
}
}
Here is my entire code
package model;
public class NQueensModel
{
private int myNumsQueen;
public int myPossibilities=0;
private boolean[][] myBoard;
private static NQueensModel myModel = new NQueensModel(4);
public static void main (String[] args) {
System.out.println(myModel.solvePuzzle());
System.out.println(myModel.myPossibilities);
// System.out.println(myPossibilities);
}
public NQueensModel(int nQueens)
{
myNumsQueen = nQueens;
myPossibilities=0;
myBoard = new boolean[myNumsQueen][myNumsQueen];
}
public boolean solvePuzzle()
{
return this.solvePuzzle(0);
}
private boolean solvePuzzle(int ncolumn)
{
if(ncolumn>myNumsQueen-1)
{
myPossibilities++;
// return true;
}
int i;
for( i =0; i<myNumsQueen;i++)
{
if(this.isSafeMove(i, ncolumn)==true)
{
this.placeQueen(i,ncolumn);
System.out.println(i+ " " + ncolumn);
if(this.solvePuzzle(ncolumn+1)==true)
{
return true;
}
this.removeQueen(i, ncolumn);
System.out.println("remove: " + i+ " " + ncolumn);
}
}
return false;
}
private int solveCount(int count, int col)
{
for(int j = 0 ; j<col; j++){
if(myModel.solvePuzzle(j)==true){
count++;
}
else if(myModel.solvePuzzle(j)==false){
return count;
}
else
{
for(int i =0 ; i<col;i++){
count = solveCount(count, col+1);
}
return count;
}
return count;
}
return count;
}
private boolean isSafeMove(int row, int col)
{
if(this.checkLowerDiag(row, col)==true ||this.checkUpperDiag(row, col)==true ||this.checkLeft(row,col)==true)
{
return false;
}
else
{
return true;
}
}
private boolean checkUpperDiag(int row, int col)
{
if(row==0)
{
return false;
}
else
{
for(int i=row, j = col; i>=0 && j>=0; i--, j--)
{
if(myBoard[i][j]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLowerDiag(int row, int col)
{
if(col==0 )
{
return false;
}
else
{
for(int i = row, j = col; i<myNumsQueen && j>=0; i++, j--)
{
if(myBoard[i+1][j-1]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLeft(int row, int col)
{
if(col==0)
{
return false;
}
else
{
for(int i = col; i>=0; i--)
{
if(myBoard[row][i]==true)
{
return true;
}
}
return false;
}
}
private boolean placeQueen(int row, int col)
{
myBoard[row][col] = true;
return true;
}
private boolean removeQueen(int row, int col)
{
myBoard[row][col] = false;
return false;
}
// public String toString()
// {
//
// }
}

Producer Consumer in java multithreaded

I'm trying to implement a Producer Consumer problem in java. I'm using a circular buffer (circular array) to for the Producer to insert items into the buffer. Following is my code:
import java.util.*;
import java.io.*;
public class Buffer
{
String a[];
int front, rear;
public Buffer(int size)
{
a = new String[size];
front = rear = -1;
}
public boolean insert(String dataitem)
{
int p;
p = (rear+1) % a.length;
if(p==front)
{
System.out.println("Buffer full");
return false;
}
else
{ rear = p;
a[rear] = dataitem;
if(front == -1)
front = 0;
return true;
}
}
public boolean empty()
{
if(front == -1)
return true;
else
return false;
}
public String delete()
{
String result = a[front];
if(front == rear)
front = rear = -1;
else
front = (front +1)%a.length;
return result;
}
public void display()
{
if(front == -1)
System.out.println("Buffer empty");
else
{
System.out.println("Buffer elements are:");
int i= front;
while(i!= rear)
{
System.out.println(a[i]);
i = (i+1)%a.length;
}
System.out.println(a[i]);
}
}
public static void main(String[] args)
{
int size = Integer.parseInt(args[0]);
Buffer b = new Buffer(size);
int ch;
String dataitem, msg;
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
}
class Producer extends Thread
{
Buffer b;
int size;
public Producer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(true)
{
synchronized(b)
{
for(int i = 1; i <= size; i++)
{
try
{ String dataitem = Thread.currentThread().getId()+"_"+i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if(bool)
System.out.println("Successfully inserted "+dataitem);
b.notifyAll();
Thread.sleep(2000);
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
}
}
}
class Consumer extends Thread
{
Buffer b;
int size;
public Consumer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(b.empty())
{
synchronized(b)
{
try
{
System.out.println("Buffer empty");
b.wait();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
synchronized(b)
{
b.notifyAll();
String dataitem = b.delete();
System.out.println("Removed "+dataitem);
}
}
}
The producer is inserting dataitems into the buffer successfully. But they aren't being consumed by the consumer.
I get the following output when I execute the program.
Successfully inserted 11_1
Successfully inserted 11_2
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
My question is how do I get the consumer to consume items from the buffer?
The major problem is that the synchronized block in your Producer is too wide. It is never letting the Consumer acquire the lock
Start by narrowing the scope, for example...
while (true) {
for (int i = 1; i <= size; i++) {
try {
String dataitem = Thread.currentThread().getId() + "_" + i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
You may also consider synchronizing the ing insert and delete methods themselves. I personally would be tempted to use a internal lock, but you could simply synchronize the methods themselves, for example...
public synchronized boolean insert(String dataitem) {...}
public synchronized String delete() {...}
As it stands, your Consumer will only ever read a single value from the buffer, but I'll let you figure that one out ;)
As a side note, I might put the wait and notify functionality directly within the Buffer, so that whenever you try and delete a value, it will wait, within the delete method for the Buffer to be not empty and allow the insert method to make the notifications itself...but that's me ;)
Equally, I might consider blocking the insert method until there is more room, but that will come down to how you want to implement it :P
Updated
Very basically, this will start giving the results you are looking for...
public class ProducerConsumer {
public static void main(String[] args) {
new ProducerConsumer();
}
public ProducerConsumer() {
int size = 5;
Buffer b = new Buffer(size);
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
public class Buffer {
String a[];
int front, rear;
public Buffer(int size) {
a = new String[size];
front = rear = -1;
}
public synchronized boolean insert(String dataitem) {
int p;
p = (rear + 1) % a.length;
if (p == front) {
System.out.println("Buffer full");
return false;
} else {
rear = p;
a[rear] = dataitem;
if (front == -1) {
front = 0;
}
return true;
}
}
public boolean empty() {
return front == -1;
}
public synchronized String delete() {
String result = a[front];
if (front == rear) {
front = rear = -1;
} else {
front = (front + 1) % a.length;
}
return result;
}
public void display() {
if (front == -1) {
System.out.println("Buffer empty");
} else {
System.out.println("Buffer elements are:");
int i = front;
while (i != rear) {
System.out.println(a[i]);
i = (i + 1) % a.length;
}
System.out.println(a[i]);
}
}
}
class Producer extends Thread {
Buffer b;
int size;
public Producer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
int i = 0;
while (true) {
try {
String dataitem = Thread.currentThread().getId() + "_" + ++i;
boolean bool = b.insert(dataitem);
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer extends Thread {
Buffer b;
int size;
public Consumer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
while (true) {
while (b.empty()) {
synchronized (b) {
try {
System.out.println("Buffer empty");
b.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
String dataitem = null;
synchronized (b) {
dataitem = b.delete();
}
System.out.println("Removed " + dataitem);
}
}
}
}

Categories