Expanding queue overwrites all previous entries with new entry - java

I have written a queuing program that allows the user to enter student objects into a queue. Here is my section of the code that I'm having trouble with:
private void resize(int max) {
assert max >= numOfNodes;
StudentListing[] temp = (StudentListing[]) new Object[max];
for (int i = 0; i < numOfNodes; i++) {
temp[i] = data[(front + i) % data.length];
}
data = temp;
front = 0;
rear = numOfNodes;
}
public void enqueue(StudentListing newNode) {
if (numOfNodes == data.length) {
resize(data.length * 2);
}
data[rear++] = newNode;
if (rear == data.length) {
rear = 0;
}
numOfNodes++;
}
The problem I am having is that when I go to add a new student into the queue and it is full, it carries out the resize method and overwrites all of my previous entries with the new student entry.
For example: a student named John gets added to the queue with a maximum size of 1. The user goes to add another student named Tom to the queue; it expands the queue, but then overwrites John. The end result is that there are two Toms in the queue instead of one John and one Tom.
I need help figuring out how to stop it from overwriting and instead add all previous entries to the newly created expanded queue, and then add the new entry to the end of said queue. Thank you in advance :)

Related

How to continuously feed items from array into two stacks, the two stacks will then feed data into queue

text file which contains a set of items like so: t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18
The two stacks and queue are limited to hold only 7 items each, I need to continuously keep feeding the items into stacks which will then go onto a queue.
Output for the stacks would be:
Lift1 :t1,t2,t3,t4,t5,t6,t7
Lift2 :t8,t10,t11,t12,t13,t14
My code:
public static void main(String[] args)
{
ECFile ecf = new ECFile();
Stack<String> lift1 = new Stack<>();
Stack<String> lift2 = new Stack<>();
Queue<String> Conveyer = new LinkedList<>();
BlockingQueue<String> bq1 = new ArrayBlockingQueue<>(7);
String[] cargo = ecf.getArray("ConstructionData6.txt");
ecf.displayArray(cargo,"");
int food = 0;
int materials = 0;
int tools = 0;
int other = 0;
bq1.offer("test");
for (int k=0; k<cargo.length; k++)
{
switch(cargo[k].substring(0,1))
{
case "F" : food++;
break;
case "M" : materials++;
break;
case "T" : tools++;
break;
default : other++;
break;
}
}
System.out.println("\nFood : "+food);
System.out.println("Materials : "+materials);
System.out.println("Tools : "+tools);
System.out.println("Errors : "+other + "\n");
for(int k=0; k<cargo.length; k++)
{
if(k < 7)
{
lift1.push(cargo[k]);
}
else if(k < 14)
{
lift2.push(cargo[k]);
}
}
System.out.println("Lift Cargo: ");
System.out.println("lift1: " +lift1);
System.out.println("lift2: " +lift2);
}
My loop pushes the data into stacks but if there are more items than they can hold the items get lost.
As I understand the question:
You feed elements into two stacks that have maximum capacity of 7
any items that do not feed into the stacks they go into the queue.
for each item in cargo:
can I put it in the first stack?
else can I put in the second stack?
else put in the queue.
here is some code pointers:
if (lift1.size() < MAX_SIZE) {
lift1.push(cargo[k]);
else if (lift2.size() < MAX_SIZE) {
....
Edit: Based on the comment bellow.
So, you need to keep track if the stack is allowed to receive items. If the stack is in emptying state, you need to push items in the next stack, and if the second stack goes to emptying state, you move to the first stack.
you need a structure to keep the state of your stack (lift). You can create a wrapper class or have an array to keep the states.
e.g:
class Lift {
int capacity;
boolean emptying;
Stack<String> stack = new Stack<>();
public Lift(int maxCapacity) {
this.capacity = maxCapacity;
this.emptying = false;
}
public boolean push(String item) {
if (!emptying && stack.size() < capacity) {
stack.push(item);
return true;
} else {
//state is emptying
emptying = true;
return false
}
}
public void pushtoQueue(Queue queue) {
while(!stack.isEmpty()) {
queue.add(stack.pop();
}
emptying = false;
}
}
and then you main loop is
boolean result1 = lift1.push(cargo[k]);
if (!result1) {
lift2.push(cargo[k]);
}

How to move position up by one when name is deleted

public void deleteQueue() {
int position;
PassengerQueue();
System.out.println("Enter Queue Position which you want to delete a customer from: ");
position = input.nextInt();
qitems[position] = "empty";
System.out.println("");
for (int look = front; look < end; look++) {
if (qitems[look].equals("empty")) {
System.out.println(look + ". " + qitems[look]);
} else {
System.out.println(look + ". " + qitems[look]);
}
}
What i am trying to do is, if a user enters a name, it will be put in position 0, if the user enters another name, it will put in posiiton 1 so 0 - bob, 1 - jon. what i want it to do is if bob position 0 gets deleted, it will change jons position from 1 to 0.
by using List there is no need to shift all the elements after delete, but if it's force to use array you can shift all in a simple loop:
public void deleteQueue() {
int position;
PassengerQueue();
System.out.println("Enter Queue Position which you want to delete a customer from: ");
position = input.nextInt();
System.out.println("");
for (int i = position; i < qitems.length-1; i++) {
qitems[i] = qitems[i+1];
}
qitems[qitems.length] = null;
}
When trying to figure out how to do an operation like this on a "low-level" object like a String array, you can always ask:
Is there a "higher-level" Java class that already exists that does the same thing?
In this case the answer is yes, there are a few... but I'm assuming you're not allowed to use them directly.
However, you can still look at their source code to see how they do exactly the same thing you're trying to do.
For example, in Android Studio, you can create a new ArrayList object... or just type "ArrayList," then right-click it... and select "go to Declaraction."
This will take you to the source code for the class you clicked on.
This is how the Android source code for ArrayList does a remove():
public E remove(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
You can see this is similar to Hamid's answer.
You can either loop through the array rearranging the positions or simply use some class that already does this for you, such as a linked list for example, which implements the remove(int index) method.
Put
qitems[position-1] = qitems[position]
inside of a for loop to cycle through each index that is after the one deleted.

Shifting history in command-pattern with undo/redo?

I'm having a problem concerning a command pattern with undo/redo function. The simple problem is, when my history is full, I want to remove the least recently used command from the history and add the new one on execute.
I got this code snippet from my professor:
public class CommandHistory implements CommandInterface{
private static final int MAX_COMMANDS = 2;
private Command[] history = new Command[MAX_COMMANDS];
private int current = -1;
#Override
public void execute(Command command) {
current++;
if (current == MAX_COMMANDS){ // if full, then shift
for (int i = 0; i < MAX_COMMANDS - 1; i++){
history[i] = history[i+1];
}
}
history[current] = command;
history[current].execute();
}
In really doubt the if-clause is incorrect, because the current command index remains 2 and only command at index 0 is shifted to 1. But he says this is the way to go. What am I missing?
The loop itself is fine, but two problems:
You're quite correct that when current == MAX_COMMANDS is true and you do the loop, current is incorrect and needs adjusting.
From a maintenance perspective, current == MAX_COMMANDS is the wrong comparison, it should be current == history.length. (Otherwise, it's easy to change the initialization of history to use something other than MAX_COMMANDS but forget to change every check like current == MAX_COMMANDS.)
I would check current before incrementing it, and only increment it if you're not shifting the contents down:
public void execute(Command command) {
if (current == history.length - 1){ // if full, then shift
for (int i = 0; i < history.length - 1; i++) {
history[i] = history[i+1];
}
} else {
current++;
}
history[current] = command;
history[current].execute();
}

remove(int index) LinkedList Self-Implementation

I am trying to learn performance of LinkedList in comparison to ArrayList
I have made my removal method as follows
Data In the LinkedList, which is being removed is about 1million elements.
My Problem, After Removing All Items: This is the Time Recd.
If I Use Java LinkedList remove(int index) Time: 2000 nanoseconds
If I Use my Custom remove(int index) Time: 34407000 nanoseconds
Could someone please look at my code and tell me where I am going wrong. I am actually suppose to remove the data by index positions, since the comparison I am trying to attain are by index positions for ArrayList.
public Object remove(int index)
{
checkElementIndex(index);
return unlink(getNode(index));
}
private Object unlink(ListNode node)
{
final Object element = node.item;
final ListNode next = node.next;
final ListNode prev = node.prev;
if (prev == null)
{
first = next;
} else
{
prev.next = next;
node.prev = null;
}
if (next == null)
{
last = prev;
} else
{
next.prev = prev;
node.next = null;
}
node.item = null;
size--;
return element;
}
private ListNode getNode(int index)
{
if (index < (size >> 1))
{
ListNode node = first;
for (int i = 0; i < index; i++)
{
node = node.next;
}
return node;
} else
{
ListNode node = last;
for (int i = size - 1; i > index; i--)
{
node = node.prev;
}
return node;
}
}
private void checkElementIndex(int index)
{
if (index < 0 || index >= size)
{
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
// BOTH THE LIST CONTAIN 1million items.
startTime = System.nanoTime();
for (int i = linkedList.size()-1; i >= 0; i--)
{
linkedList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList Removal Time: " + duration);
// This is the Java Collection LinkedList
startTime = System.nanoTime();
for (int i = linkedList.size()-1; i >= 0; i--)
{
javaLinkedList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("My Removal Time: " + duration);
I appreciate, each and every possible suggestion. Thank you.
(continued from comments)
No problem! First step is to download a profiler (I use VisualVM. There are other ones out there, but unfortunately I'm not familiar with them...) Once that's downloaded, go ahead fire that up.
The next step is figuring out how to attach the profiler to your process. Once you start up VisualVM, you should see a list of running Java programs on the right. You can ignore that for now. The trick is that you'll need a long-running program to have enough time to attach the profiler to the process. For something like your code, an easier way would be to use Scanner.nextLine() to block the program in between loops, sort of like this:
Scanner scanner = new Scanner(System.in);
scanner.nextLine(); // This stops the program and waits for user input.
// This will give us all the time in the world to attach the profiler.
// Your code
for (int i = linkedList.size()-1; i >= 0; i--)
{
linkedList.remove(i);
}
scanner.nextLine(); // Same thing here
for (int i = linkedList.size()-1; i >= 0; i--)
{
javaLinkedList.remove(i);
}
Now, go ahead start your program. If you go back to VisualVM, you should be able to see your program!
Now double-click on your program. You should see a few messages appear in the console in your program, and the view in VisualVM should change. Go to the "Sampler" tab, click "CPU", then go back to your program and hit enter.
What you see should be pretty self-explanatory. On the left are fully qualified method names with package + class, and a bar representing the portion of CPU time that methods use. Use that to identify where your program is spending all its time. And there you go! If you need more time to profile, just add more elements to the linked lists.
Just a word of caution though; profiling can be deceiving, because if another method is messing up your linked list structure it can make a perfectly good method work far harder than it has to. For example, I had to implement HashMap as part of a school assignment. When I profiled I noticed that the code to look in buckets was taking up 97%+ of CPU time, even though there was nothing wrong with it. Turns out that a test to get a proper bucket had >> instead of <<, turning the HashMap into a LinkedList instead! So while profiling is a good start (and usually is the only thing you need to do to identify problems), just keep in mind that the errors could be elsewhere.
I hope that this helped!

Counting levels in Breadth First Search (Distance between start node and goal node)

Can anyone help me how to count the visited levels of a graph using Breadth First Search in Java?
Here is my method, I have start node (str) and end node (goal), when the loop reach the goal node it should be stopped.
What I want now is counting the levels from start node to end node.
public void bfs(String str,String goal) {
int strInx = findIndex(str);
vertexList[strInx].wasVisited = true;
theQueue.insert(strInx);
int v2;
boolean bre = false;
while (!theQueue.isEmpty()) {
System.out.println(vertexList[theQueue.getFront()].label);
int v1 = theQueue.remove();
while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {
vertexList[v2].wasVisited = true;
System.out.println("--V2--->"+vertexList[v2].label);
theQueue.insert(v2);
if(goal.equals(vertexList[v2].label)) {
bre=true;
break;
}
}
if(bre)
break;
}
for (int j = 0; j < nVerts; j++) {
vertexList[j].wasVisited = false;
}
}
You can use one of the following approaches to track the current level:
Use two queues instead of one: currentLevelQueue and nextLevelQueue
Use one queue to track the nodes another one to track the associated level
Use a wrapper class that includes a level field and store instances of this class in the queue
i had a similar requirement where i had to count the levels in a bfs algo. I did it by creating a of hashmap of levelMap>..
the integer is the level number...
nodes is the list of nodes at the same level...
this helped me find out when to go to the next level by incrementing the level counter...while doing bfs..
pseudo code:
HashMap<Integer, ArrayList<Node>> levelMap = new HashMap<Integer, ArrayList<Node>>();
....
int currentLevelFromMap = getCurrLevelFromMap(levelMap, currentNode);
currentLevel = currentLevelFromMap + 1;
if (currentLevelNodeList.size() != 0) {
levelMap.put(currentLevel, currentLevelNodeList);
}
currentLevelNodesList is the list of the nodes from a particular iteration of algorithm

Categories