nested while loops - outer vs inner conditions - java

In the example below does the inner while loop continue to execute it's statements 2 after the outer loop condition becomes false? Or once the outer while loop condition becomes false the ENTIRE loop exits including the inner while loop even though the condition for the inner while loop is true?
while (becomes false){
statements 1;
statements 1;
while ( true at the time the outer loop condition become false){
statements 2;
statements 2;
}
}
println("print something interesting");

It may help to understand how a while loop works. If you write:
while(myCondition) {
doSomething();
doSomethingElse();
}
println("print something interesting");
Then it basically becomes (in pseudo-code):
1. if myCondition continue to line 2, else go to line 5
2. doSomething()
3. doSomethingElse()
4. go to line 1
5. println "print something interesting"
As you can see, the condition is only checked at line 1. If myCondition becomes false during line 2, for instance, there's nothing to short-circuit the block. (If you need that, you have to manually re-test myCondition and call break if it's false.) This is true even if doSomething() is replaced by a while loop, for loop, or anything else.
So, if "statements 2" make the outer loop condition false, nothing will stop. The program will go on its merry way until the inner loop finishes, at which point the out loop finishes its iteration (since there's nothing after the inner loop within the outer loop's block) and goes back to re-test its condition to see if it should start another iteration. Only then does the outer loop check its condition.
To make it a tad more explicit, here's how your code basically works:
1. if outer-condition continue to line 2, else go to line 9
2. statements-1
3. statements-2
4. if inner-condition continue to line 5, else go to line 8
5. statements-2
6. statements-2
7. go to line 4
8. go to line 1
9. println "print something interesting"
So, outer-condition is only checked at line 1. If it becomes false at any point, the loop won't even notice until it gets to line 1, which will only happen once it gets to line 8 (or the first time it hits line 1 to start the while loop, of course).

the inner loop will only be executed (tested for condition) if the outer loop is true. otherwise if outer loop breaks, nested loop has no chance to get executed.

First of all, while loop conditions are only checked at the start of each iteration.
If, at the start of an outer loop iteration, the condition is false, contol is transferred the statement following the outer loop, thereby bypassing the inner loop.

Think of code in a code block (aka the curly brackets) as a door. If you do not meet the requirments to enter the door then you cant see anything inside. So no the inner loop (since the outer loop is false) will not execute.

Use a local variable for controlling the loop so you can check for this value in loop 2.

Related

Is there a better way to access the last element in a for loop in Java

[edited the post to be more clear]
The code below is supposed to represent a number of trial runs, and within each trial assume a is the number of cases that need to be checked.
while(testCaseAmt > 0) {
for(int i = 0; i < a; i++) {
if(some condition)
//code when i is not the last element
//then I would like to break/return here.
if(i = a - 1)
//code when i is the last element
//then if the above if statement never runs during the a amt of trials
//i will print out something else
}
testCaseAmt--;
}
My question is if there is another way to access specifically the last element within a for loop to give it specific instructions. I want to loop through a set trials and if they meet the first condition, I stop the loop immediately and return. However, if the condition isn't found I still need to print out not found.
Cheers.
To me this seems related to "off-by-one errors" or "fencepost errors", see here.
If the code you're executing when i is not the last element isn't too complex, it could be better to just end the for loop one iteration earlier and write the specific code for the last element outside the for loop.
Adding an if statement inside a for loop where you know it will only be true at the very last iteration could be seen as bad-style.
You can define a boolean conditionMet = false before the for-loop and iterate until i < a-1.
If some condition applies, execute your code, then set conditionMet = true and break out of the for-loop.
After the for-loop, check if !conditionMet and in this case, execute the code for the last element.

Variable assignment inside for loop [duplicate]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
This is a very simple for loop:
for(int i=0;i<=100;i++)
{
System.out.println(i);
}
I know how it mostly works, but I don't understand how the i++ works at the end: its supposed to add 1, if I'm correct, but when it prints out the i, it prints out 0 and then 1.
Why doesn't it just start out with 1 because of the i++? Why does it still just print out the original value instead of the i++ value?
A for loop works as follows:
Initialization is done (int i=0 in your case; only executed once)
Condition is checked (i<=100 here), if condition is false leave the loop
Code within the braces is executed (System.out.println(i); in your case)
Update statement is executed (i++)
Goto 2.
It's similar to this while loop :
{
int i = 0;
while (i <= 100) {
System.out.println(i);
i++;
}
}
i is incremented only at the end of each iteration.
Because the increment is evaluated after the first execution of the loop body. This is by design, and remember that programmers generally treat 0 as the first number. For example, with arrays and String(s) the first element is 0.
The Java Tutorial on The for Statement says,
The for statement provides a compact way to iterate over a range of values. Programmers often refer to it as the "for loop" because of the way in which it repeatedly loops until a particular condition is satisfied. The general form of the for statement can be expressed as follows:
for (initialization; termination; increment) {
statement(s)
}
When using this version of the for statement, keep in mind that:
The initialization expression initializes the loop; it's executed once, as the loop begins.
When the termination expression evaluates to false, the loop terminates.
The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.
Here it is how it works
The for statement is used to repeat a block of statements enclosed in curly braces. An increment counter is usually used to increment and terminate the loop. The for statement is useful for any repetitive operation, and is often used in combination with arrays to operate on collections of data/pins.
There are three parts to the for loop header:
for (initialization; condition; increment / decrement) {
//statement(s);
}
The initialization happens first and exactly once. Each time through the loop, the condition is tested; if it's true, the statement block, and the increment is executed, then the condition is tested again. When the condition becomes false, the loop ends.
Credits : For
If you use ++ operator as prefix like: ++var; then, the value of operand is increased by 1 then, only it is returned but, if you use ++ as postfix like: var++; then, the value of operand is returned first then, only it is increased by 1.
For example,
class Example
{
public static void main(String[] args)
{
int var = 1;
System.out.println(var++);
System.out.println("\n" + ++var);
}
}
the following program prints
1
3
In the prefix form, the increment or decrement takes place before the value is used in expression evaluation, so the value of the expression is different from the value of the operand. In the postfix form, the increment or decrement takes place after the value is used in expression evaluation, so the value of the expression is the same as the value of the operand.
Think of the i++ as the statement that says "Use then increment"
The value of i will first be used in the loop and then incremented by 1.
So the loop is executed once, then the declaration and incremental statements checked.

How to break continue a nested for-loop inside a while-loop?

Can I use break on a nested for-loop to get back to outer while-loop and use continue from inside the for-loop to force the while-loop to keep going? I can not get the for-loop conditions into my while-loop conditions so the while-loop might stop if I cannot continue on a specifically meet situation.
while(...some conditions...){
...print stuff
for(...some instances are arrays, condition loop array...){
if(...index meets conditions...){
...print once, some arrays might meet condition on multiple index
break; //to prevent multiple printings
}
continue; //i don't want to force another while iteration if(false)
//or is this continue for(loop) anyway?
}
continue; //is this not essentially a while(true) loop with no return?
}
The reason I can not get the for-loop conditions into the while conditions is because there are more if conditions between the two loops like if(array == null) and if-condition x == true getArray() needs to be called if array is not passed in. Most of the time condition y and z print from while-loop but sometimes condition x is met so I need the for-loop. It's after the printing of the for-loop if(index true)) I need the while-loop to go again that I'm stuck with? Sometime this might happen from while-loop conditions anyway but I can see that it wont always, further more if for-loop if(index false)) is meet I don't want to force the while loop as this could get costly in run time processing and could possibly result in an endless loop.
PS I am a junior programer, I'm not even sure it this is possible?
or makes sense, sorry if its a stupid question
you can name your loops like this:
namedLoop: for(...) {
// access your namedloop
break namedLoop;
}
You can break with label.
Here is a complete example showing it:
https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/java/nutsandbolts/examples/BreakWithLabelDemo.java
Basically the code is similar to this:
:myLabel
for (...) {
for(...) {
...
break myLabel; // Exit from both for loops
}
}
continue and break apply to the immediate current scope, so if you're inside the for, it will apply to the for.
You can store the comparison result on a boolean variable to check if you want to continue.
I'm not a big fan of break and continue, it hinders readability in my opinion. You can acheive the same behavior using a different code structuring.

Scenario with while statement

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.

Can a termination variable in a condition of for loop be changed inside the loop?(Java)

in Java, when using a for loop, you need to write a termination condition of course. This is my for loop:
for(int i=1; i<=infix.length()-2; i++){
if(infix.charAt(i)==' '){
infix=infix.substring(0,i)+infix.substring(i+1);
}
(infix is a string i got as a parameter). As you can see, I'm using substring inside the loop, which shortens the length of infix, which means that the termination condition of the loop is changed after every single iteration.
My question is this: Is the value "infix.length-2" saved at the beginning of the for and doesn't change later on? Or it changes every time, and if so, what happens with i? When will the for stop? Is there a chance for an index out of bounds or something like that?
Thank you very much in advance! :D
The string length gets calculated every loop, and your for could throw an IndexOutOfBoundsException if your string becomes too short.
IMHO yours is a very bad practice, for loops are intended to make a determined number of loops and should never be stopped, also their stop condition should never be changed inside the loop, you should use a while if you don't know how many iterations you want to do. But this is my personal opinion :)
Yes, you can change the upper limit. No, it's not cached at the beginning of the loop. Yes, anything you do wrong might cause errors -- but this is neither especially dangerous or uncommon. On the contrary, it's quite common.
you can put multiple end criteria in a for loop, just for a sample syntax
for(int i = 0; i < 2 || i< 5; i++)
System.out.println(i);
As a short hint: Your for-loop is equivalent to the following while-loop
{
int i=1;
while(i<=infix.length()-2) {
if(infix.charAt(i)==' '){
infix=infix.substring(0,i)+infix.substring(i+1);
}
i++
}
}
That means the condition of a the for-loop is evaluated in the same way as the condition of a while-loop. There is nothing special about it.
My question is this: Is the value "infix.length-2" saved at the beginning of the for and doesn't change later on? Or it changes every time, and if so, what happens with i?
It changes with every iteration of the for loop. i gets incremented, with each iteration.
When will the for stop? Is there a chance for an index out of bounds or something like that?
The for loop will stop when the termination condition is true.
i<=infix.length()-2.
i initialized to 1 will result in a loop that terminates if the length
If you modify the termination condition variables with incorrect logic, then you have a chance of running into an infinite loop.

Categories

Resources