6

Can you please tell me how does this java code work? :

public class Main {
    public static void main (String[] args)  {
        Strangemethod(5);
    }
    public static void Strangemethod(int len) {
        while(len > 1){
            System.out.println(len-1);
            Strangemethod(len - 1);
        }
}
}

I tried to debug it and follow the code step by step but I didn't understand it.

update: sorry I didn't mention that I know the result of this code but just want to know the steps of the execution..

5
  • 2
    @Nikita, I guess the OP did not write it, just found it somewhere and is trying to understand it. Commented Jun 18, 2010 at 15:02
  • 7
    @Nikita Rybak; Be nice to people trying to learn how to code. :-) Commented Jun 18, 2010 at 15:04
  • @ Nikita , I didn't write it, I am just asking to know the steps of the execution.. Commented Jun 18, 2010 at 15:09
  • 1
    I lol'd tht the site name is Stackoverflow and this would eventually cause that. Isn't that funny? Commented Jun 18, 2010 at 16:48
  • 1
    Use If statement instead of while loop. I've got unexpected results with while loop and recursive functions. Commented Jun 24, 2016 at 10:14

8 Answers 8

13

That'll print 4 3 2 1 1 1 1 1 1...

And get stuck in a loop because nothing ever modifies len in the scope of the while loop. The first calls (with len=5, 4, then 3) go through one loop iteration, and are left waiting for Strangemethod to return. When when len=2, the while loop calls strangemethod(1), and since len is not greater than 1, the while loop finishes and that call returns. But len is still 2 in the bottom-most remaining whle loop, so it calls strangemethod(2) again. And again. And again.

if() would've been more appropriate than while().

Sign up to request clarification or add additional context in comments.

3 Comments

Or possibly, decrementing len within the loop, which would produce a sort of tree of values.
@Dave: Strangemethod(5) -> 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 (like Tom said, a triangle)
If you want that kind of evil, calling strangemethod with len-- (or, even more evil, --len) would've been similarly entertaining. :)
2

If I'm not mistaken, isn't this causing an infinite loop?

Once strangemethod(1) returns the strangemethod(2) would print 1 again and then call strangemethod(1) again.

Are you forgetting to decrement len after the strangemethod call?

Comments

2

EDIT :SORRY For the first reply didnt realise it..it will cause an infinite loop

Here is a simple flow - for e.g len =5

 public static void Strangemethod(5) {
            while(5 > 1){
                System.out.println(5-1);
                Strangemethod(5 - 1);
            }
public static void Strangemethod(4) {
            while(4 > 1){
                System.out.println(4-1);
                Strangemethod(4 - 1);
            }
public static void Strangemethod(3) {
            while(3 > 1){
                System.out.println(3-1);
                Strangemethod(3 - 1);
            }
    public static void Strangemethod(2) {
            while(2 > 1){
                System.out.println(2-1);
                Strangemethod(2 - 1);
            }
    public static void Strangemethod(1) {
            while(1 > 1){//goes back to original(above) call and then an infinite loop since len was never  decremented

            }

Prints 4 3 2 1 1.....

3 Comments

But within a single invocation of Strangemethod, len is not decremented.
... and then the call to Strangemethod(2) will loop forever.
It wasn't wrong.... it just didn't address the glaring issue with the function. Still a valid response. :)
2

I know that I'm almost 13 years late to the party, but I ran into this problem in a quiz at my college, I answered it wrong and I couldn't figure out why it's behaving like this. So I took some time and I believe I can explain it in a way that would make sense to everyone.

Iteration #1. of the while loop declared inside the method call strangeMethod(5);

    public static void strangeMethod(5) {
        while (5> 1) {
            System.out.println(4);
            strangeMethod(4);
        }
    }

Because 5 is greater than 1, the code within the while block got executed, so, now we can see the print statement in the console, but what's really important for you to notice here, is that we did not run a second iteration of this while loop, in fact, we did not even finish the first iteration, it got paused midway so that it can execute the recursive call of strangeMethod(4), and it will never get a chance to finish

To make sure we're on the same page, your answer to the question "how many iterations of the while loop executed in the call strangeMethod(5); completed?" should be not even one iteration.

BUT, we did call strangeMethod(4); now this is a fresh method call, the while loop within it will start to execute since its continuation condition is met, 4 is greater than 1, BUT, just as the previous call, it will not even finish a single iteration and it will call strangeMethod(3);

Iteration #1. of the while loop declared inside the method call strangeMethod(4);

    public static void strangeMethod(4) {
        while (4 > 1) {
            System.out.println(3);
            strangeMethod(3);
        }
    }

Iteration #1. of the while loop declared inside the method call strangeMethod(3);

    public static void strangeMethod(3) {
        while (3 > 1) {
            System.out.println(2);
            strangeMethod(2);
        }
    }

Iteration #1. of the while loop declared inside the method call strangeMethod(2);

    public static void strangeMethod(2) {
        while (2 > 1) {
            System.out.println(1);
            strangeMethod(1);
        }
    }

Now, the call of strangeMethod(2); is different, because it is the only call of strangeMethod() that will actually get to iterate more than once.

You see, the continuation condition for the while loop is, if 2 is greater than 1 which will always be true, just like all the previous call have been. The difference in this method is that the strangeMethod(1); call will not interrupt and pause the while loop, it will start executing, see that the continuation condition while (1 > 1) is not met, and since there is no other code in the call of strangeMethod(1); for it to execute, strangeMethod(1); will actually finish, allowing us to proceed from where we left off, which is to finish iteration #1 of strangeMethod(2); start iteration #2 of strangeMethod(2); check that the continuation condition for the while loop (2>1) still holds true, execute the print statement, execute the strangeMethod(1); call which will finish, and allows us to start iteration #3 of strangeMethod(2); and since we have no base case for when len == 1, strangeMethod(2); will keep iterating indefinitely.

So, the call of strangeMethod(2); is unique in that all the code to be executed within it will actually get executed, allowing the while loop within it to iterate.

Iteration #2. of the while loop declared inside the method call strangeMethod(2);

    public static void strangeMethod(2) {
        while (2 > 1) {
            System.out.println(1);
            strangeMethod(1); //Is now just some dead code 
        }
    }

Iteration #3. of the while loop declared inside the method call strangeMethod(2);

    public static void strangeMethod(2) {
        while (2 > 1) {
            System.out.println(1);
            strangeMethod(1); //Is now just some dead code 
        }
    }

Now, if this is still not creating that AHA! moment, consider doing the following, adjust the code by adding a simple if block

    public static void strangeMethod(2) {
                if (len == 1) {
                        System.out.println(
                                "strangemethod(1) was executed and finished, 
                                The while loop within it did not run 
                                because its condition was not met
                                Thus, allowing us to move on to the second
                                Iteration of the while loop within 
                                strangeMethod(2);"
                        );
                }
        while (2 > 1) {
            System.out.println(1);
            strangeMethod(1);
        }
    }

OR

    public static void strangeMethod(2) {
                if (len == 1) {
                    System.exit(0); // which will end all the previous 
                                    // method calls, unlike return; which will 
                                    // only end strangeMethod(1); but keep 
                                    // strangeMethod(2) still active and                                    
                                    // running
                }
        while (2 > 1) {
            System.out.println(1);
            strangeMethod(1);
        }
    }

For anyone who finds my answer helpful, I would greatly appreciate it if you'd up-Vote it.

Comments

1

You don't say what you expect the code to do. However, the obvious point of note that the len variable does not change value within the Strangemethod method - it could have been declared final. Possibly what you wanted to do was decrement it with --len; (equivalent to len = len - 1;).

Comments

1

Try adding len--; after Strangemethod(len - 1);. It won't send you into an infinite loop then. Alternatively, you could do

System.out.println(--len);
Strangemethod(len);

4 Comments

might as well change len - 1 to just len and put the len-- before the recursive call.
@Matthew: Indeed, though there are a variety of ways of using -- here, as shown by the other variant that I just added.
very true... or course with M.H. asking what the method does.. it it would probably be best to have the len--; on it's own line for now. (You could have fun and even move it to the while expression.)
Oh yeah, that's true. while (len-- > 1)
0

This code will loop forever.

The result of len - 1 is never stored in the while loop so it can't exit and when len = 2 it'll just sit there outputting 1s.

It's unusual to use a while in recursive functions. I'd typically expect to see an if in its place, which would give you the output:

4
3
2
1

If you really do need the while then I'd rewrite the loop like this:

while(len > 1)
{
  len--;
  System.out.println(len);
  Strangemethod(len);
}

This will output:

4
3
2
1
1
2
1
1
3
2
1
1
2
1
1

Comments

-3

Also, I think someone should point out that len is never decremented so you get an infinite loop. I see that only 7 people have mentioned that so far.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.