So basically, I have a programming assignment, and it involves two lines at an airline, one for frequent flyers and one for regular flyers. I have a for loop set up that, each time it runs, it determines whether some amount of frequent flyers gets in, some amount of regular flyers, or no one. For a frequent flyer, it is supposed to take 3 minutes to service a flyer, with one "minute" being a single iteration of the loop. For the regular flyers, it will take 5 minutes to service one person, again, with one iteration of the loop being a single minute. How can I determine when someone in the line has been serviced? As in, how can I pull someone out of the line whenever 3 or 5 iterations of the loop have occured, respectively. I'm utilizing a linked list.
I'm not sure I entirely understand your question, but I think I got the idea.
You could use break; to exit the loop (if that's what you're trying to do), and to test the amount of times the loop has been executed, you can use an int. It will look something like this:
int i = 0;
for(initialization, condition, iteration){
//Your code
if(i == 3 | i == 5){
break; //If you have your own method to "pull someone out of the line",
//then insert it here instead of using break, and also insert i = 0.
}
i++;
}
Related
I am taking an intro to java course and I am taking a practice quiz. These quizzes are not graded and do not count towards our grade so I thought I would post here.
Under normal circumstances, I would just copy the code and paste it into an IDE but I wanted to know if there is a way to think about this logically so I can figure out the answer. On real exams, we are not allowed to use eclipse or anything like that to figure out an answer and this question would take way too long to do it by hand and count how many times it goes through the for loop.
Here is the question:
How many times does the print statement in the for loop execute?
for(int i = 0; i <347589; i++) {
System.out.print("Give me coffee!");
}
You can basically just take the upper bound of the for loop as an answer, which is 347,589 in this case. To arrive at this answer, consider a for loop with a much smaller bound:
for (int i=0; i < 5; ++i) {
System.out.println("Give me coffee!");
}
By inspection, we can see that this loop will execute when:
i = 0
i = 1
i = 2
i = 3
i = 4
It won't execute when i = 5, because that fails the condition. So, it executes five times, which is the same as the upper bound of the for loop. We can extrapolate this to the loop in your problem to get 347,589 as the answer.
There is no general way to figure out how many times a while loop will execute before running it. This fact is known as the undecidability of the halting problem. For loops are just syntactic sugar for while loops, so this applies to for loops as well. The halting problem is the subject of a great many awesome books, among which Gödel, Escher and Bach by Douglas Hofstadter.
However, the for loop you give is extremely simple: it increases i until i no longer satisfies i < 347589. The variable i starts at 0 and increases one by one: i++ is equivalent to i = i + 1;. So i takes all the successive values: 0, 1, 2, 3, 4, ...,347588 and every time, the line System.out.println("Give me coffee!"); is executed.
Then i takes the value 347589 and no longer satisfies i < 347589, so the loop halts.
In total, "Give me coffee!" was printed 347589 times.
If you don't like the syntax for for loops, your code is equivalent to the following code using a while loop:
int i = 0;
while (i < 347589)
{
System.out.print("Give me coffee!");
i = i + 1;
}
As you have a simple for-loop that executes only one statement multiple times, you can simply count. You might know that the loop starts with i=0 with the first execution and adds 1 after each execution until the condition i<347589 is false. So:
i=0 -> once (1.)
i=1 -> twice (2.)
...
i=347588 -> 347589 times (347589.)
i=347589 -> loop stops.
so the print statement will be executed 347589 times.
In the course they might just want to check your knowledge towards the coding basics. In these type of problems you should notice most importantly 4-5 things.
1- Starting point of index.
2- Ending point of index, also check whether that value in included or not.
3- Increment/Decrement of index, whether index is increased/ decreased by 1 or some other value or pattern.
4- Is their any break statement inside the loop, which will also indicate that loop will run till specific condition.
In the example you gave starting point is 0 and end point is 347589 (excluded) with increment of 1, so loop will run. 347589 - 0 + 1( 0 based index) = 347589 times.
Obviously, FOR loop is not Java specific question.
To understand FOR loop properly let's take an easy example.
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
This code will print all number from 0 to 10 (Excluding).
So, the range 0-10 has 10 different values:
0
1
2
3
4
5
6
7
8
9
When i becomes 10 FOR loop statement (i<10) will not be satisfied and the loop will be broken.
So, in you case "Give me coffee!" will be printed 347589 times with the same logic.
I have written a java program in which I am supposed to know that if the two nested for loops can finish their execution in 4 seconds or not If they finish their execution in 4 seconds then the program should continue else break the loop. I have three list A ,B and C and I am performing some operation and adding it to the list B. Even for the small inputs to the list A and C like 3, 6, 8, 4, My program throws run out of memory error
I am using one outer for loop for calculating time. If two for loops couldn't finish their execution in 4 seconds the loop should be terminate. I am using one count variable to keep track of the for loop execution even if for loop finished their execution before 4 seconds i am terminating the outer for loop.
Here is my code :
while(!(A.isEmpty())){
ArrayList<Long> B = new ArrayList<>();
for(long start = System.currentTimeMillis() ; start < System.currentTimeMillis() + 4 * 1000 ; ){
for(long i : A){
for(long j : C){
if(i!=j){
B.add(Math.abs(i-j));
}
}
count++;
if(count==A.size());
break;
}
}
}
What is wrong with this code ? How should I make it correct ?
Thank you.
I think this design isn't really robust. Instead of calling the time function within that loop, I think you could be looking into using two threads here:
Thread A kicks of thread B, and waits for n seconds
Thread B does the computation
When thread A wakes up, it simply checks if the computation is done
Alternatively, your main thread kicks of A and B; and A just comes back and tells you: time to check the results of B now.
And for your real problem; I guess one contributor is here:
B.add(Math.abs(i-j));
You see B (really bad name for a list of numbers btw!) taks Long objects. So that little call there creates at least one Long object per iteration. And you iterate over A and C. Without any sleeps or delays there. This means that your code is doing nothing else but iterating loops and creating new objects to fill that B list.
Now: how many loop iterations do you think you will see in 4 seconds? Enough to create millions and millions of objects?! And then: a dynamically growing list is nice, but you understand what it means when an ArrayList constantly goes over its capacity and needs to grow?! You understand that this means creation of new arrays, and copying around of all values?!
What I am saying is: look carefully how much work is really going on there; and how much (un)boxing of primitive/reference long/Long you got in your code.
One (maybe easy way) to test these ideas: change your code from using List of Longs into using fixed arrays with long values. That will have a nice side effect - it will force you think upfront about how many array slots you actually want to create. In your solution, you just keep looping and adding new objects (as said; leading to constant re-capacity increase operations for your B list).
Statement while(!(A.isEmpty())) will run an infinite loop causing B to be instantiated infinite times.
As a result causing OutOfMemoryError
You Have an infinite loop, while(!(A.isEmpty)) will always be true because inside of your for loops you are never removing any elements from A. This will cause you to add an infinite amount of elements to B becuase of B.add(Math.abs(i-j));
The loop needs to scan an external file, from the bottom to the top. BUT...
When the loop has scanned 6 items from the external file, it needs to stop.
Then, IF there are less than 6 items to scan from the list on the external file it needs to print all of the those items to the screen.
I know how to do a loop that can scan the file from top to bottom using inFile.hasNext(); etc. I just don't know how to do from bottom to top and then define how many iterations I want the loop to actually do, with an if statement that is something like:
if (number of iterations < 6 print all)
{
JOptionPane.showMessageDialog(iteration1, iteration2, etc...)
}`
else if (number of iterations >= 6 only show the first 6 the loop has scanned)
{
JOptionPane.showMessageDialog(iteration1, iteration2, etc...)
}
Sorry about my awful pseudo code, just really stuck and this is the last part I need to do to finish my system!
any help would be brilliant!
I would recommend using a predefined class for reading backward. As to looping:
for(int i = 0; i < 6 && /* test for more input*/; i++)
{
JOptionPane.showMessageDialog( /*next input*/ );
}
I'd try instantiating an array with 6 empty strings and then concatenate the item you get in each iteration of the loop with the corresponding empty string in your array.
Afterwards you can check for your < 6 condition and depending on the result concatenate the string you want to give to your JOptionPane
You can't read a file from bottom to top. Instead, read the file (top to bottom) keeping the last (up to) 6 items read. When you hit the end if the file, test if you you have 6 items or not and act accordingly.
Use a LinkedList object, which allows removal of the element of the list via removeFist().
You could just store all items and use only the last 6, but that may mean using a lot of memory if the file is very large.
Okay so I was working on understanding the bubble sort algorithm this code works but I dont understand the while statement? It doesnt have a condition in the parentheses and I dont know why it keeps on running and why it stops.
public class BubbleSort {
int temp;
boolean flag;
int[] bubbleSort(int[] bs)
{
flag=true;//What?
while(flag)//Whats happening here? Whats the condition
{
flag=false;//Wouldnt that quit the while loop?
for(int i=0;i<bs.length-1;i++)
{
if(bs[i]>bs[(i+1)])
{
temp=bs[i];
bs[i]=bs[i+1];
bs[i+1]=temp;
flag=true;//What does this signify?
}
}
}
return bs;
}
public static void main(String[] args)
{
BubbleSort thisone = new BubbleSort();
int[] bacon = {1,0,3,2,4,5};
int[] potato = thisone.bubbleSort(bacon);
for(int i=0;i<potato.length;i++)
{
System.out.println(potato[i]);
}
}
}
It may be easier to understand in pseudo-code, without all the language-specific stuff:
didSwap = true # force loop entry
while didSwap: # keep going until sorted
didSwap = false # mark sorted
for each element except last:
if element > next element:
swap element, next element
didSwap = true # swapped, mark possibly unsorted
The didSwap (a) variable is initially set to true to ensure the loop is entered.
Upon entering the loop, it is immediately set to false so that, it nothing sets it back to true, the loop will exit after this iteration. That means the default behaviour for a loop iteration is to complete, then exit the loop (all talk of iterations here and below refer to the outer loop, the while one, not the inner for each one).
Now look at what sets it back to true. It's the swapping of any items in this iteration. When that happens, you know that you need at least one more iteration of the loop because you may have disturbed the order of items you've already done earlier in this iteration.
Consider the case of the following numbers and you're part way through the first iteration (no swaps have yet been done):
5 10 15 7 20
^^
Running from left to right, you've arrived at the 15 and you know that the first three numbers are already in order. But then you get to the 7 and you swap it with 15 to fix the order of those two. Now you have:
5 10 7 15 20
^^
and you can see that, because you've made a change to the sequence before where you're processing, you may have disturbed the order (in fact you have in this case), so you'll need at least one more pass to check and/or fix that.
Bottom line, because of the sequential nature of processing the list (left to right), you can only be certain it's sorted if you reach the end of an iteration and no swaps have been performed during that iteration.
That's why the flag method is used. More naive implementations simply do something like n * n iterations for a list of size n. That also guarantees that the items will be sorted at the end but doesn't give you the early exit possibilities of the flag method. You can see the problem immediately if you give it an already-sorted list of a thousand elements.
The naive approach will process the entire list one thousand times, the flag method only once.
(a) I prefer didSwap myself since its use and intent is clearer.
The flag is a typical Bubble sort optimization. If you go through the entire array and make no changes, then the array is sorted, and you can stop. while(flag) means "as long as the array still needs to be sorted."
In other words, the flag short circuits the sort. It lets you stop early if possible.
Before entering the loop flag is set to true (otherwise it would not be able to enter)
As soon as it enters it sets flag to false
If a condition is met, the flag is set to true
Back to the top of the loop - is flag set ? If false, it will break out, otherwise back to step2
flag=true;//What?
flag was declared earlier as a boolean, now it's being initialized to true (so that the loop will execute at least once)
while(flag)//Whats happening here? Whats the condition
A condition is just something that evaluates to a boolean, in this case the boolean variable flag is the condition.
flag=false;//Wouldnt that quit the while loop?
It won't jump out of the loop, that would take a break or return, so execution will continue into the for loop.
flag=true;//What does this signify?
This is set when if(bs[i]>bs[(i+1)]) evaluates to true, signalling that the array is not sorted yet.
It must be really basic but I need help. For example, you store monster information in an array, and do for~loop to make each monster attacks/moves in their turn like this
for( i <- 0 to monsters.length-1) monsters(i).act
Then some monsters die during the loop and you have to delete some elements in the array while the loop is still on going. Then the next item in the array could be not really the the next one you want to process.
is there any fast/smart way to make sure each item in an array will be proceed once and only once within the loop, even if you really had to make change to the array during loop?
Scala's collections generally don't assume that you'll be manipulating them while they're using a method like foreach (or executing a for loop). If you want to do things that way, the easiest class to use is Java's java.util.concurrent.ConcurrentSkipListMap.
// This helps you use Java collections like Scala ones
import collection.JavaConversions._
case class Monster(name: String, hp: Int) {}
val horde = new java.util.concurrent.ConcurrentSkipListMap[Int,Monster]
horde put (0, Monster("wolf",7))
horde put (1, Monster("orc",3))
for (h <- horde) println(h) // Prints out both
Iterator.iterate(Option(horde.firstEntry)) {
case None => None
case Some(e) =>
val m = e.getValue
if (m.name=="wolf") horde.remove(1) // Kill the orc
else if (m.name=="orc") horde.remove(0) // Kill the wolf
Option(horde.higherEntry(e.getKey))
}.takeWhile(_.isDefined).foreach(_=>())
for (h <- horde) println(h) // Prints out just the wolf
Now, granted, this is rather a mess, but it does work, and it gives nice random access to your monsters. You have to maintain the keys in a sensible order, but that's not too hard.
Alternatively, as others have indicated, you could add an isAlive or isDead method, and only act on monsters that are alive. Then, after you've passed through the list once, you .filter(_.isAlive) to throw away all the dead monsters (or .filter(! _.isDead)), and run it again.
I would either use a conditional statement to check the monster's isAlive property in the loop before I called act, or do that check inside the act method itself.
I imagine that your monster[i] is not going to die on his turn, but rather off some other hapless monster?
If you're hooked on arrays, or don't mind the processing time (and for what you're doing, i reckon you don't care), just keep a boolean on each monster of isDead.
If a monster dies due to some ... i dunno, reason, just mark the "isDead" as true.
Then, in your monster "act" method, just check if the monster "isDead" or not.
After each loop, you can just prune the list to keep the alive monsters (move all the ones that are alive to a new list and begin again, prune the list in place, whatever is easier for you).
EDIT: This first graph misinterperets your question. However, my solution should still work for you.
What you're asking for is a thread-safe array - one that can be accessed by multiple "threads" of execution at a time. Seeing as you're new to Java, my guess is that your game is not going to be multithreaded, and so if you delete an item in an array, that's going to happen for sure before your next loop runs.
That said, if you really want to, you can add a "monster.dead" boolean function to your array, and set that to true whenever a monster dies. In your loop, then, you'd say:
for( i <- 0 to monsters.length-1)
if (monsters[i].dead == false)
monsters(i).act
Most likely, though, you won't run into this issue.
Edit: just reread your post, and realized that you'll be deleting monsters as your array is running. Remember that each line you execute happens sequentially, so when you remove monsters[i], it will be gone the next time the for loop is evaluated. If you have an array of monsters with 5 monsters in it and you delete the second one, when the loop executes again,
monsters.length - 1
is going to evaluate to 3 now. You'll never run into a moment where you hit a deleted array element.
If you delete an entry in an array, this element would be null.
Therefore you should check every element of your array, e.g.:
for(int i = 0; i <= array.lenght - 1; i++) {
// check null
if(array[i] != null) {
// do stuff
}
}
Hope this helped, have Fun!
make a copy of the original array, and traverse the copy.
if a monster would remove a monster, it would be removed only from the original
Deleting elements from an array while looping over it is generally a horrible idea. What if you delete an element before you reach it in the loop? Should you not actually delete it until the end of the loop, or should you skip over it?
I recommend something more like this:
var monsters = ... initial list of monsters ...
monsters = for (m <- monsters; if m.alive) yield { m.act; m }
Take advantage of yield and if in conjunction with the for loop, which allows you to build a new list.