Circular Queue Array Insertion Case - java

I have the code for the implementation of this pretty close to being done, what is causing my IndexOutofBounds error seems to be happening in one case of inserting into the queue. Any ideas? At the start of my class i set the rear and front to be -1, and the count to be 0. The array has a max size of 100. There is a isfull class that tests to see if the count is the max size.
public boolean insert(int n){
if (isFull()){
//not inserted
return false;
}
else{
//make it the first in queue if queue is empty
if ( front == -1 && rear == -1){
front++;
rear++;
list[front] = n;
list[rear] = n;
count++;
return true;
}
//not at end of queue, add to end
else if ( (count+1) <= 100 ){
rear++;
list[rear] = n;
count++;
return true;
}
//else add to front
else{
//update rear
rear = ((count+1)%100)-1;
list[rear] = n;
return true;
}
}
}
This code so far inserts a number into the array in this order:
0. Check to see if its full. If it is quit.
1. If the queue is empty, make it the first item in there.
2. If the queue is not empty or full, check to see if the back of the array doesnt exceed the max spots. If it doesnt, add it to the end.
3. If the queue is not empty or full, but the back of the queue is full. Loop around and insert it into the beginning of the array.
The problem is in the case where for example:
- The array is filled with numbers 1-100. The array is full at this point.
- Remove the front, so then the array goes from 2-100 with the first slot being empty.
- Insert the number you just removed, this causes the error. At this point the count+1 doesn't exceed the max spots, so it tries to add it to the rear. But since the last spot is full, it doesn't loop around, throwing a array out of bounds exception. What can i add for it to check if the last spot is filled and to add to the beginning of the array in that case?
My remove method:
public int remove(){
//if empty return -1
if (isEmpty()){
return -1;
}
else{//else remove
front++;
int x = list[front-1];
count--;
return x;
}
}

public boolean insert(int n){
if (isFull()){
//not inserted
return false;
}
else{
//make it the first in queue if queue is empty
if (isEmpty()){ //use empty
front=0;//just set it
rear=0;//just set it
}
list[rear] = n;
rear = (rear+1)%100; //just rewind it when it reaches 100 index 0 must be free at this point
count++;
return true;
}
}
I suppose count is the number of elements, so remove should do count--. in this case count is always <100 because the array is not full after u checked for that... so the only thing you must do is to rewind the rear counter;
additionally remove should do front = (front+1)%100;
public int remove(){
if (isEmpty()){
return -1;
}
else{//else remove
int x = list[front];//reorder
front = (front+1)%100;//rewind
count--;
return x;
}
}
empty() and full() should use count
front points on the the element to remove() next
last always points on the next free spot (or on front which is the next free spot too)

Related

Display Nodes at the same depth not working

void wordsAtDepth() {
int depth = 0;
int numOfNodes;
Queue queue = new Queue(32); // Make a new Queue called queue.
queue.insert(root); // Insert the root into the queue
// While queue is not empty we will continue the while loop
while (!queue.isEmpty()) {
// numOfNodes keeps track of how many times we are going to
// continue the for loop in the current while loop.
numOfNodes = (int) Math.pow(2, depth);
// for loop will continue until i is equal to or is greater
// than numOfNodes.
for (int i = 0; i < numOfNodes; i++) {
// Current will equal to the removed element from the
// queue.
Node Current = queue.remove();
// If Current does not equal null then print current
// and insert its' left and right child.
// If Current does equal null then do nothing go to the
// next iteration of the for loop
if(Current != null){
System.out.print(Current.cData);
queue.insert(Current.leftChild);
queue.insert(Current.rightChild);
}
}
// Makes new line every time we finish the while loop.
// Which means new line for the next iteration of the
// while loop to separate the different depths.
System.out.println(" ");
depth++;
}
}
Nodes contain char values. For the word OPTIMAl it prints correctly, but for words like HAPPY or SUPERMAN they print incorrectly. For example: SUPERMAN: S PU ER AMN SPUERAMNPUERAMN ERAMNAMNNEMNNAMNN AMNNNNAMNNNNNNNN NNNNNNNN
Instead of using numOfNodes = (int) Math.pow(2, depth); the code works when I use the numOfNodes = queue.length(). But I WANT to use numOfNodes = (int) Math.pow(2, depth); since the for loop will should loop for the ammount of Nodes at a depth. Since the number of Nodes in a depth is 2^Depth.
If you expect the number of nodes at a certain depth to be that power of 2, then you must make sure to deal with the case where your tree is not perfect, because then -- even if your tree is complete -- the bottom level will not be fully filled.
The simple fix seems to be that you always add 2 entries to the queue for every entry you pop from it. So change this:
if(Current != null){
System.out.print(Current.cData);
queue.insert(Current.leftChild);
queue.insert(Current.rightChild);
}
to this:
if(Current != null){
System.out.print(Current.cData);
queue.insert(Current.leftChild);
queue.insert(Current.rightChild);
} else {
queue.insert(null);
queue.insert(null);
}

Java. Discard cards in poker using an array of indices

I am trying to write code for a poker game to delete cards at certain indices using an array.
The code i have so far is the following and is not working.
ncard is the number of cards currently in the hand. any help would be appreciated.
/**
* discard the indexed cards from the Hand.
* #param indices the indices of cards to delete.
* #return true if all Cards deleted, false if not.
*/
public boolean discard(int[] indices){
int i = 0;
while (i < indices.length){
if (indices[i] < 0 || indices[i] >= ncard)
{
return false;
}
for (int in = indices[i]; in < ncard; in++){
cards[in] = null;
ncard--;
}
i++;
}
return true;
}
It looks like you have the cards in a static array, and are setting the discarded indices to null. If you discard n cards and then try to discard a card at index 52-n, the method will return false and not discard any more cards.
You should probably use some dynamic data structure, such as a stack or a list, to store the cards. If you must use an array, here's how to go about fixing your problem:
You are not discarding cards at the indices, you are discarding every card between each given index and ncard (which doesn't represent the index of the last card since the nulls are at arbitrary locations). That for-loop should be replaced with
cards[indices[i]] = null
deletedCards++;//You should initialize this before the loop
After the loop, you should put this code:
Arrays.sort(cards, new Comparator<Card>(){
public int compare(Card a, Card b){
return Boolean.compare(a==null,b==null);
}
});
It sorts the nulls to the back of the array, and keeps the order otherwise same. Then you decrement ncards by deletedCards.
I highly reccomend for-loops in this case, since all this i++ stuff makes the code hard to understand
public boolean discard(int[] indices) {
// check if all indices consumed are valid
for(int index : indices) {
// i just use your validation, don't know, if this is correct though
if(index < 0 || index >= ncard)
return false;
}
// remove cards
for(int index : indices) {
cards[index] = null;
ncard--;
}
return true;
}
My guess is that the problem comes from the validation, but I would need more information to really solve that problem...
Maybe this would be a better validation sorting out indexOutOfBounds (negative and positive) and the attempt to discard more cards than ncard:
if(index < 0 || index > (cards.length -1) || indices.length > ncard)
return false;
EDIT: I assume that cards is an array that has the size of your card deck and all cards that the player does not have are null values?

java - referencing elements in an arraylist whilst removing some

I have a for loop looping through each element in an arrayList performing someMethod() on them, depending on the result of that method I either want to keep or remove that element from the list. for example:
int returnResult;
for (int i=0;i<4;i++){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
}
}
My question is; if i have say 5 elements in the list and on the second iteration through the loop (so when i=1), I remove that element, when I go through the 3rd iteration will arrayList.get(2) be referencing what was actually the 4th element? i.e. does it immediately reduce the stack size?
Yes, it does. In order to get around this, you can iterate through the array in reverse.
int returnResult;
for (int i=3;i>=0;i--){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
}
}
This pops them off from the end, and doesn't affect the elements left to go through.
Replace your code with this :
int returnResult, limit = 4;
for (int i=0; i < limit; i++){
returnResult = someMethod(arrayList.get(i));
if (returnResult == -1){
arrayList.remove(i);
limit--;
}
}

Inserting into an ArrayList<Occurrence> using Binary Search

So this method is passed an arraylist of Occurences, which each contain a string and a frequency. The frequency is the only important part here. But what I need to do is use binary search to insert the last element in the arraylist into the sorted position. Every time I run this code, the insertion position is printed as -1. Am I missing something in my code?
I need to keep track of the indexes in the array I hit during binary search, which shouldn't be too difficult, but explains the return type.
public ArrayList<Integer> insertLastOccurrence(ArrayList<Occurrence> occs) {
ArrayList<Integer> path = new ArrayList<Integer>();
int targetFreq = occs.get(occs.size()-1).frequency; //gets the frequency of the thing we want to insert
//if the array is just 1 value, don't do anything
if(occs.size() == 1){
return null;
}
int start = 0; // The start of the search region
int end = occs.size()-2;// The end of the search region is 1 less than the last position
int position = -1; // Position of the target
// While there is still something list left to search and
// the element has not been found
while (start <= end && position == -1) {
int mid = start + (end - start) / 2; //int mid = (start + end) / 2; // Location of the middle
// Determine whether the target is smaller than, greater than,
// or equal to the middle element
if (targetFreq < occs.get(mid).frequency) {
// Target is smaller; continue the left half
end = mid - 1;
}
else if (targetFreq > occs.get(mid).frequency) {
// Target is larger, continue the right half
start = mid + 1;
}
else {
// Found it!
position = mid;
}
}
System.out.println(position);
return path;
}
So, do I understand this right? You have an ArrayList that is sorted with the exception of the last element (at size()-1) and you want to find the index this element has to be inserted after to regain the sorted property?
I suppose, with the presented code, such an index is only found if the ArrayList contains another element that equals the last (to be inserted) one because position is only set to mid if targetFreq equals the frequency of one of considered elements. Since the last element is never considered (end = size()-2) it is very likely that no equal element is found.

N-Queens in Java using Stacks, Keeps taking the same route after backtracking

Title pretty much says it all. I've been working on this and just can't figure out a way to prevent it from happening. Perhaps some way to store invalid placements? Or how would I implement a way for it to 'resume' from the last time it was at this row so it doesn't just pick the same value again?
Ignore the while i, its just for debugging. Same with the prints.
import java.util.Stack;
public class NQueens {
//***** fill in your code here *****
//feel free to add additional methods as necessary
//finds and prints out all solutions to the n-queens problem
public static int solve(int n) {
//***** fill in your code here *****
//Scaffolding code from Stacks.pdf
//------------------------------------------------------------------------------------------------------------------
// Create empty stack and set current position to 0
Stack<Integer> s = new Stack<Integer>();
int column = 0;
int row = 0;
int solutionsCount = 0;
int i = 0;
//Repeat {
//loop from current position to the last position until a valid position is found //current row
while (i < 5){
for(column = 0; column < n ;column++) {
//if there is a valid position
System.out.println("Top of for loop");
System.out.println("Column/index for = " + column + "; Row is: " + row);
System.out.println("Stack size = " + s.size());
System.out.println();
if (isValid(s, column, row)) {
s.push(column);
//push the position to stack, set current position to 0 // move to next ro
row++;
column = 0;
}//if
}//for
//if there is no valid position
if(!isValid(s, column, row) || column >= n){
//if stack is empty, break // stop search
if(s.size() == 0){
break; //stop search
}//if
//else pop from stack, set current position to next position // backtracking to previous row
else{
s.pop();
column++;
row--;
}//else
}//if
//if stack has size N { // a solution is found
if (s.size() == n){
solutionsCount++;
printSolution(s);
//pop from stack, set current position to next position // backtracking to find next solution
s.pop();
row--;
column++;
}//if
else {
}//else
i++;
// Make sure to change this when not bug testing for 4x4
}//end for loop
//update the following statement to return the number of solutions found
return solutionsCount;
}//solve()
This looks like homework, so here are some pointers:
You are modifying the column variable after the for loop. Obviously, you intend its value to carry over into the next iteration of while. But then the first thing you do when while starts again is you set column to 0 with for (column = 0; ....), which overrides its value. What information is column supposed to carry from one iteration of while to the next?
You are setting column to 0 inside the for loop but it will be incremented to 1 with column++ before the next for iteration.
You are using column in the if statement immediately after the loop. What do you expect the value of that variable to be after the for loop completes?
After the for loop you have two if statements that are trying to check for the same condition -- whether the for loop found a solution. Only the second if is much clearer about it. Do you even need both ifs?
You are putting column values into the stack, but when you pop them off the stack, you just discard them. Don't you have some use for these values?

Categories

Resources