For Loops and Logical AND + OR [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Why does this code take not run?
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
if(i>0){
if((staticWallLoc[i--][j]&4)>0){staticWallLoc[i][j]=staticWallLoc[i][j]|1;}
}
if(j<10){
if((staticWallLoc[i][j++]&8)>0){staticWallLoc[i][j]=staticWallLoc[i][j]|2;}
}
if(i<10){
if((staticWallLoc[i++][j]&1)>0){staticWallLoc[i][j]=staticWallLoc[i][j]|4;}
}
if(j>0){
if((staticWallLoc[i][j--]&2)>0){staticWallLoc[i][j]=staticWallLoc[i][j]|8;}
}
System.out.println(i+" "+j);
}
}
By the way, staticWallLoc[11][11] is a two dimensional array that has 11 indexes in each dimension (0-10).
Just wondering why my program literally cannot get passed this code.

Dude - why are you decrementing in the loop body the same variables you're using to control the loop counter?!?
Sounds like "one step forward, two steps back", doesn't it ;)?
SUGGESTION:
Run the debugger, single step through a few iterations, and carefully note what happens to "i" and "j".
How soon do you think either or both will reach "11" ;)?

Inside your if(i > 0), i is decremented by staticWallLoc[i--]. Change it to staticWallLoc[i-1], and do the same for j.
if(i>0){
// Try something like this instead
if((staticWallLoc[i-1][j]&4)>0){
staticWallLoc[i][j]=staticWallLoc[i][j]|1;
}
}
You will also want to change your [i++] to [i+1].

In your loop, you have statements like if (i>0) {staticWallLoc[i--][j].... These are directly altering the loop index. So, when i is 1, it is changed back to 0. When the loop is incremented, it goes back to 1, and then 0 again, creating an infinite loop.
Do you perhaps mean to use staticWallLoc[i - 1][j]..., etc. ? This gets the desired index without changing the loop index.

rather than using i++ i-- etc in your code, just use offsets i-1 or i+1.
General rule of thumb: in for loops, don't mess with the for loop variables within the body.
(there are exceptions to the rule, but this doesn't look like an exceptional case)

Without knowing what the heck the contents of your array is it's hard to say. Might it be because you're modifying the values of i and j on the fly with -- and ++? Do you mean to be keeping those values constant and doing something like:
if((staticWallLoc[i+1][j]&1)>0){staticWallLoc[i][j]=staticWallLoc[i][j]|4;} // changed i++ to i+1

Once j reaches 10, it does not get incremented in the "if (j < 10)" section, but it gets decremented in the "if (j > 0)" section, so j will end the loop at 9, then get incremented back to 10 by the loop management. So you will have an infinite loop with i = -1/0 (since it gets decremented and incremented in the loop) and j = 9/10 (for the same reason).

You do a j-- in the last if once j >=10. The loop will stuck at j==10.
It's not a very good idea to manipulate the loop variable :)

Related

Using If-Statement as test condition for For-Loop in Vb.net

I've been writing some software in Vb.net and I've come to a point in the program where it would be best if I could place an if-statement in the header of a for-loop.
For example, in java, I could achieve what I need like so..
for (int I = 0; myArray[I].compareTo("") == 0; I ++)
{
'code here
}
Unfortunately in Vb.net, all I know how to do is increment one number to a given number in a for-loop. I am aware however, that what I need to do can be accomplished using an if-test inside the for-loop
For I as Integer = 0 To myArray.length 'only possible test is comparison between two ints
'code here
If myArray(I).compareTo("") <> 0 Then
Exit For
End If
Next
Its not a big deal having to do this but if there is a way to streamline this more into the for-loop control then I would like to know for now and future reference.
So my question is, is it possible to check an if-condition (other than comparing two numbers) inside the header of a for-loop in Vb.net?
Update: In response to #Olivier Jacot-Descombes 's answer, I just wanted to clarify that I know while loops are used to test if-conditions in loops, but they lose the functionality of auto-incrementing possessed by for-loops. In Java, for-loops can do both of these. Which is why I'm wondering if Vb.net has the same functionality all within the header of a for-loop control somehow.
Use a While-Loop instead
Dim i As Integer = 0
While i < myArray.Length AndAlso String.IsNullOrEmpty(myArray(i))
'Code here
i += 1
End While
In VB a string can be empty ("") or Nothing (null in C#). In order to cope with both situations use String.IsNullOrEmpty(s).
AndAlso (unlike And) ensures shortcut evaluation. I.e. if the first condition is not True then the second will not be evaluated. We need this here, otherwise the array would throw an "Index out of bounds" exception. Note also that the array index goes from 0 to array.Length - 1.
But you can also exit from a For-loop with Exit For
For I As Integer = 0 To myArray.Length-1
'code here
If Not String.IsNullOrEmpty(myArray(I)) Then
Exit For
End If
Next
But exiting a loop like this can make the code unreadable. The problem is that the For-loop has now 2 exit points and loop and exit conditions defined at different places.
There is also a Do...Loop statement allowing you to test the condition at the end of the loop.
The short answer is no. Visual Basic languages don't have anything like the C/java style for() loop.
The longer answer is that depending on what you want, you might not even need a loop.
Dim a = {"a", Nothing, "", "b"}
' this will print from 0 to 1, but Array.IndexOf returns -1 if value is not found
For i = 0 To Array.IndexOf(a, "") - 1
Debug.Print(i & "")
Next
For Each item In a : If item = "" Then Exit For ' this is actually 2 lines separated by :
Debug.Print("'{0}'", item)
Next
For Each item In a.TakeWhile(Function(s) s > "") ' TakeWhile is a System.Linq extension
Debug.Print("'{0}'", item)
Next
a.TakeWhile(Function(s) s > "").ToList.ForEach(AddressOf Debug.Print) ' prints a
a.TakeWhile(Function(s) s > "").ToList.ForEach(Sub(s) Debug.Print(s)) ' prints a

Index Error with a For-Loop and a LinkedList

I am trying to make a little game on my own to get used to Java and I just had a problem with LinkedList Index. I found a way to patch my problem but I still don't understand why my first solution is not working. This code:
for (int i=0; i <= PlanetList.size(); i++)
{
g.drawImage(PlanetList.get(i).planetImage, PlanetList.get(i).xPos, PlanetList.get(i).yPos);
}
Gave me a java.lang.IndexOutOfBoundsException but this code:
for (int i=1; i <= PlanetList.size(); i++)
{
g.drawImage(PlanetList.get(i-1).planetImage, PlanetList.get(i-1).xPos, PlanetList.get(i-1).yPos);
}
The thing is ... my index start at 0 in both case. Why does the first gives me an Error?
Your last index in the first example is going above the allowed index range. For e.g., if the size of the list is 10, the allowed index range is [0 9]. In your first loop, it goes up to 10 (i <= PlanetList.size()). Change the terminal condition to i < PlanetList.size() to fix your issue.
The alternate is to use no indices to access elements in your list as #GhostCat has suggested:
for (Planet planet : PlanetList) {
g.drawImage(planet.planetImage, planet.xPos, planet.yPos);
}
This is called for-each loop in Java
The other solution is to simply use the index-free version to iterate "collections" that was introduced years ago:
for (Planet planet : PlanetList) {
g.drawImage(planet.planetImage, planet.xPos, planet.yPos);
As a nice side effect, that also eliminates the code duplication that you had in your example.
And while we are at it: you are somehow violating the "tell dont ask" principle. Meaning: you are asking your planet object to give all the details you need to draw it. In good Object Oriented designs, you avoid that. Instead, you tell objects to do something. In other words: you could change your planet class to
public void drawWith(Graphics g) { ...
With that the above code can be rewritten as:
for (Planet planet : ... ) {
planet.drawWith(g);
YOU are getting the Out of bounds error because the variable i declared in the for loop is running for less than equal to condition of planetlist size as i starts from zero it will go till the linked list size but since you have given less than equal to it goes in the loop one more time therefore out of bounds exception .Just change the for loop condition to i less than linked list size it will work

List size has unexpected value

Suppose the following situation in a loop:
LinkedList<String> myList = someMethodReturnsList();
int start = 0, end = 0;
while (end < myList.size() && someOtherCondition)
++end;
List<String> subList = myList.sublist(start, end);
... (do stuff and possibly alter list)
start = end;
I'm having a situation where only sometimes, that call to sublist will throw an IndexOutOfBoundsException. Given my first test of end < myList.size(), this troubled me, so I wrote some debug code. My debug code told me that somewhere between that while loop and calling sublist, my end value ended up being 34 while myList.size() was returning 33.
How is that even possible? There are no other threads that can be operating on this list in my program, so how did my loop check pass and increment end to 34?
EDIT: this consistently happens at a particular point in my code's execution, so it's not a fluke error, but it doesn't happen with every input that this function has, which makes this even stranger.
What you are describing is impossible.
Actually, the only way for this to happen is your own debugging: There are IDE features like code elements inspection that execute parts of the code while the application is paused on a breakpoint.
You have to be changing the value of end with the debugger tools.
My guess is along the lines of what #Jalitha said, off by one: the sublist call should be:
List<String> subList=myList.sublist(start,end-1);
The reason that you are sometimes getting the correct number probably has to do with your someOtherCondition.
Remember that size() is 1 more than the last index and subList works on indexes.
I would have put this in a comment but unable due to reputation :(
Aha! I've figured it out through careful debugging.
Turns out, on the loop iteration where this exception occurs, the end value is starting at 34. Thus, the increment loop passes, and there is an index error.
The reason is that in the previous iteration, myList.size() was 36, but over the course of that loop, 3 elements were removed.
Looks to me like a classic 'off-by-one' array error. You're likely having end equal to myList.size(), and then referencing one more ahead than you mean to.
From your while loop for e.g. if array had 5 elements:
while (end < 5 && conditions)
{
++end; //results in end being 5
}
then later on it goes
List<String> subList = myList.sublist(0, 5);
and 5 is outside the bounds as the array only has indices 0,1,2,3,4
I think you should either make it while (end+1 < 5 && conditions) or myList.sublist(0, end-1);
EDIT: Props to #Justen, for pointing out my mistake.

In a Logic When to use For loop and When to use while loop [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am beginner for the programming language , I am bit confused in the basic of looping concept can any one please tell me clearly when to use the concept of For loop and when to use the while loop so that it would be very grace full for me to my future programming,
Thanks in advance
Generally, you use a for loop if you know (Or the program can know at the time of the loop) how many times you want to run a piece of code, and while loops if you do not.
However, it is possible to use them interchangably, so while it may be a bit less elegant to use one than the other, it doesn't matter too much.
Ex:
for(int i = 0; i < 100; i++){
do stuff
}
is the same as
int i = 0;
while(i < 100){
do stuff
i++;
}
, but the former looks more elegant.
Similarly,
bool condition = false;
while(condition){
do stuff
}
and
for(bool condition = false; condition;){
do stuff
}
are the same, but generally, the while loop is considered more elegant here.
In almost all cases you could use either for or while loops. You are provided with two ways of looping to help reduce the complexity of your code across different use cases.
When to use for loops
For loops are best when you know how many iterations you want to loop before you begin. For example, if you knew you wanted to print the numbers 1 through 10 in order you know you want to loop 10 times.
for(int i = 1; i <= 10; i++)
{
System.out.println(i);
}
When to use while loops
While loops are best when you want to continue looping until a specific event occurs or a condition is met. For example, let's say you wanted to print random numbers between 1 and 10 until you came across the number 5. This may take one iteration or hundreds depending on your luck.
Random rand = new Random();
int value = 0;
while(value != 5)
{
value = rand.nextInt(10);
System.out.println(value);
}
Basically you should use a for loop if you know the number of iterations this loop has to do. Even if that number is a variable (like the length of a list) it is know at runtime.
A while loop is used when you don't know the number of iteration. You mostly check a condition that can evaluate to false after any number.
You also have the do-while and the for-each loops at your disposal. The do-while is used when you know that you have at least one iteration but the number is otherwise unkown. The for-each is used to iterate over arrays and collections. It can do something for each element contained.
A for loop will give you the option to perform any or all of these three things:
Instantiate a starting iteration value (int i = 0)
Define a boolean condition on which iteration may continue (i < 10)
Provide an incrementation step (i += 2)
A valid for loop can look like this:
for(; ;) {
System.out.println("This will run forever!!!");
}
A while loop only gives you the boolean condition, which is mandatory.
You typically use the for loop when:
You know the size of the elements you must iterate over
You typically use the while loop when:
You don't know the size of the elements you must iterate over
You want to busy-wait on some value or variable
For loops are used when you know how many times you need to loop. While loops are used to loop until an event occurs.
Also, note that whatever you can do with a for loop, you can do it with a while loop (just add a variable that increments in the while loop and uses it to break out of the loop when the variable reaches a certain value).
This is one of those things that folks typically pick up by experience. First thing to realise is that any for loop can be decomposed into a while loop
for ( initialise; test ; go on to next )
can be expressed as
initialise;
while(test) {
go on to next
}
I'd suggest trying for a little while to use only while loops. What you will then find is that some of your while loops start to feel a little clumsy.
initialise;
while(test) {
my really interesting code here
go on to next
}
and you find that
for ( initialise ; test; go on to next ) {
my really interesting code here
}
reads more clearly. One common example being working your way through an array.
for ( int i; i < array.length; i++ ){
something with array[i];
}

Value (not index) greater than 3 in array causes java.lang.ArrayIndexOutOfBoundsException

I'm a novice programmer. This may be a simple problem but I've never seen this before. First of all, let me clarify that I'm not even trying to manipulate the index. Here's the part of the code that is causing the exception:
int[] bumpercatcher = new int[4];
//time variable that helps control events
int time = 0;
public void setup()
{
bumpercatcher[0]=4;
bumpercatcher[1]=4;
bumpercatcher[2]=4;
bumpercatcher[3]=4;
As you can see I'm trying to set them all equal to 4 at the start of the program. This causes the arrayindexoutofbounds exception. If I set them all equal to 0~3 then there is no problem (until I set them to a value greater than 3 later in the program). I don't understand it.
-it doesn't matter if I set the array size to 10, I still get the same exception
-it doesn't matter if I set only one of the values (i.e. at index 1, which is definitely within bounds of the array). same exception
Is there something I'm doing wrong? Thanks.
well, here' the entire code if you want to take a look(not too long, 1 class, bad programming practies): http://dl.dropbox.com/u/33501308/Pong.java
Here's the html from which you can see the program from (not much to see. it just freezes instantly.): http://dl.dropbox.com/u/33501308/bin.zip
by the way I'm using eclipse.
I don't really know what SSCEE is. sorry
Your posted code file includes loops along the lines of
for(int j: bumpercatcher) {
if(bumpercatcher[j]>5)
...
}
This is an issue. This is a different kind of loop than a traditional for loop. It is an extended or enhanced for, also called a foreach. It reads "for each integer j in array bumpercatcher do x." You are taking your element j (a value) and using it as an index to the array. When your value exceeds the maximum index, you will get an exception.
Write your code with a proper for loop if you want to access by index, or try simply restructuring your logic like
for (int j : bumpercatcher) {
if (j > 5) // j is the value!
...
}
I'm not sure what the problem is, but a far more readable way of doing this would be with a for loop:
for(int i = 0; i < bumpercatcher.length; i++) {
bumpercatcher[i] = 4;
}

Categories