java - why is this recursive method exceeding what I expected - java

Doing a very simple program to test out recursion. The program prints something until the number is not greater than 0.
public class TestIt {
public static void print(int f){
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
}
}
the code above is called from the main program like this.
public static void main(String[] args) {
TestIt.print(2);
}
Maybe I'm finally losing my mind, but the amount of times the program prints is exceeding what I expected. If I send 3 to the method then the program prints 7 times. Any ideas as to why?

Because you did wrong
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
you are calling the method print f in the loop times
and as it is recursive it will be called f-1 times recursivelly
so it will b f fatorial times
remove the while loop and will work as you want

This is because everytime the call comes off the stack, f is still what it was originally, and then it continues with the while loop. So for 2:
while(f>0){
System.out.println("Not today");
f--;
print(f);
}
First run, subtracts from 2, results in one. (Print count = 1) Resursive call:
Subtracts again, 0, recursive call: (Print count 2)
While loop is never entered. returns:
0, while loop is not executed, reuturns:
While loop is run again, recursive call: (print count = 3)
Passes zero, while loop not entered, return
While loop terminated, exit method
For 2 it prints three times, but this grows for every number passed in. To fix this do:
if(f>0){
System.out.println("Not today");
f--;
print(f);
}
Remember recursion usually is to avoid loops, so if you find yourself using both, this is usually a red flag

Related

Code written after infinite loop executes

The following code shows an empty infinite loop and code written after the loop prints "Hello, World".
In this example, the println statement to print the statement synchronously and thus theoretically, after the infinite loop nothing should be printed, but still when on running the code, it prints "Hello, World".
So, why is the code written after an infinite loop executing?
public class Main{
public static void main(String[] args){
for(int i=0; i>=0; i++){}
System.out.println("Hello, World"); // This is printed on the console
}
}
I tried searching goole and stackoverflow for it, but could not find an answer for the problem.
Thank you.
When i becomes greater than max value(2147483648 - that can be represented in 32 bits), it overflows to its min value.
It runs exaclty Integer.MAX_VALUE times, because Integer.MAX_VALUE + 1 is Integer.MIN_VALUE, a negative number.
You can visualize your code like this :
class Main {
public static void main(String[] args) {
int i = 0;
for(i=0; i>=0; i++){}
System.out.println("Hello, World : "+ i);
}
}
This loop is not an infinite loop. It goes until the i reaches Integer.MAX_VALUE. Then i becomes Integer.MIN_VALUE which is a negative value. Run the code below and check the output.
int x = Integer.MAX_VALUE;
x++;
System.out.println(x);
If you want the loop to be infinite use,
for ( ; ; ){
}
Either the compiler smartened up and knew that nothing was done in that loop (which shouldn't matter, because even the for conditions can edit stuff)
or i looped 2 million something times and overflowed into negative numbers, making it less than 0.

Recursion! I'm creating a method that counts back up and then down to a certain number, but I keep getting stuck in an infinite loop

So, I am currently creating a method for an assignment using recursion. I need to take an int, then print going down until it hits 0. After that, I need to print going up until it hits the original number, then stopping. Here's my code so far.
public static void recursivePrinter(int levels)
{
final int start = levels;
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
recursivePrinter(levels - 1);
}
return;
}
You don't reach the return; statement. the code always go in the else statement. to keep track of the starting number you could use a global variable . also you need to add a condition where the recursion should finish. so you can try some thing like this :
static int start = 10;
public static void recursivePrinter(int levels)
{
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
// recursivePrinter(levels - 1);
start-- ;
}
return;
}
In an attempt to provide a meaningful answer to help future visitors (as opposed to the comment thread on the question above)...
The initial problem was two-fold:
The method had no condition in which it doesn't recursively call itself. Which results in an infinite recursion. There must always be some condition by which the method stops recursion.
The method was locally storing a value that it doesn't need, and the logic was incorrectly assuming that value won't be different for each call to the method.
Essentially, a recursive method almost always follows a basic structure:
method(argument) {
terminating condition;
state change or method action;
recursive call;
}
Depending on the state change or the method action, this can be a bit more complex. But the basic components are generally always there in one form or another.
In your case, the argument is an integer, the terminating condition is testing whether that integer is a known value, the state change is changing the integer, the method action is printing the integer, and the recursive call is invoking the method with the new integer.
Based on your comment above:
It's supposed to count down from 3 (3, 2, 1) and then back up to 3 (1, 2, 3).
Consider the following pseudo-code (so as to not do your homework for you) structure:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
}
This would be a great time to step through the code in your debugger and see what a recursive method call actually does. Each time the method is invoked, it's an isolated action unaware of any other invocations of the method. It's "building a stack" of calls to itself. When the terminating condition is reached, that stack will "unwind" and those calls will all return to each other in reverse order.
Given this, printing the numbers "counting back up" is a natural result of just printing it again in the method:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
// more method action
print level
}
That last operation simply prints the value a second time. But it does so after the recursive call, therefore after all printing of lower numbers done within that recursive call, regardless of how many there are.

In the following function why After showing Hello(6,5,....1),then space shows increment in counter?

In the following function why After showing Hello(6,5,....1),then space shows increment in counter?
private void myMethod(int counter)
{
if (counter == 0)
{
System.out.println("");
}
else
{
System.out.println("Hello" + counter);
myMethod(--counter);
System.out.println("" + counter);
}
}
Program Output when 6 is passed to method:
Hello6
Hello5
Hello4
Hello3
Hello2
Hello1
0
1
2
3
4
5
The second print is first called if the recursion is fully done, this means it counts backwards, since the last called method finishes first.
If that's what you mean.
(not actually code but used for a diagram)
When using myMethod(3):
mM(3)->|prints: "Hello3"
|mM(2)-------------->|prints: "Hello2"
|prints:.... |mM(1)-------------->|prints: "Hello1"
|prints.... |mM(0)----------->|prints: ""
|prints....
because each else has three statements, and they do them in order from top to bottom, the first print statement is executed first, and then the recursion happens next, which temporarily skips the the second print until the base statement 0 is reached, and then it goes backwards and does the second print for each else. (if this is what you're asking)

Number pyramid,beginner recursion tracking difficulty?

I am a beginner in JAVA, and I am having some difficulties tracking recursion and understaning it fully and so here I have the code for a program that if we write 3, it will output:
1
12
123
12
1
Or if we write 5, it will output
1
12
123
1234
12345
1234
123
12
1
public class Aufgabe3 {
private static void printSequenz(int n) {
if(n<1) {
return;
}
printLoToHi(n-1);
printMany(n);
printHiToLo(n-1);
}
private static void printHiToLo(int n){
if(n<1){
return;
}
printMany(n);
printHiToLo(n-1);
}
private static void printLoToHi(int n){
if(n<1){
return;
}
printLoToHi(n-1);
printMany(n);
}
private static void printMany(int n){
for(int i=1;i<=n;i++){
System.out.print(i);
}
System.out.println();
}
public static void main(String[] args) {
printSequenz(5);
}
}
Now here is what I don't understand. For example at the method printHiToLo it calls the method printMany(n), and then it calls itself for n-1, and this repeats until n is greater than 0. But I don't understand how the method printLoToHi works? How does it ever reach the printMany method? If it just calls itself until n is greater than 0. This is really confusing to me... Thanks to anyone that helps me out :)
private static void printLoToHi(int n){
if(n<1){ // This is the base case that terminates the recursion.
return; // You'll always have one - sometimes more.
}
printLoToHi(n-1); // This is where the recursion takes place.
printMany(n); // But when n < 1 it returns to here and continues on.
}
So you see it does indeed get called; only after the base case (n < 1) is reached.
An easy example would be if you called it with printLoToHi(1)...
It will pass the if condition.
It calls itself with n - 1 (0) as an argument.
This time it fails the condition and returns.
n == 1 in our original method.
printMany(1) is called.
Look, your functions are executed line by line. So in printLoToHi recursive call is executed and then printMany is called.
For example how works printLoToHi(3):
It checks if 3 less than 1. Then calls printLoToHi(2).
It checks if 2 is less than 1. Then calls printLoToHi(1).
It checks if 1 is less than 1. Then calls printLoToHi(0).
It checks if 0 is less than 1. It is, so it returns.
Then printMany(1) is called.
Then printMany(2) is called.
Then printMany(3) is called.
You can consider a recursive call as a single function which does something and don't think how it works. You can assume it works and write other part of function. If that part is correct - the recursion is correct.

While and do while loops

I'm new to this site and also very new to Java and I'm trying to understand the do while loops
Question: What is the output and why?
public class DoWhile {
public static void main(String[] args) {
int i = 1;
do {
System.out.println("i is : " + i);
i++;
} while(i < 1);
}
}
I get that the output is "i is : 1" but I'm trying to understand why. It stops once it hits while because i isn't less that 1, right?
Just trying to get my head around it so any help will be appreciated.
Yes. Correct.
do { } while (condition);
This will perform the code at least once, regardless of the condition. After the first execution it will check the condition, which will evaluate to false (1 is not smaller than 1) and thus it will stop.
Yes, the output is 1 because in a do-while loop the statements within the do block are always executed at least once.
After the do block is executed the i value becomes 2 and the while block is not executed.
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once
Yes, the output is
i is : 1
The do-while loop will always execute at least once, because the condition isn't evaluated before the loop is entered; it's only evaluated at the end of each iteration. This is in contrast to the while loop, whose condition is checked before the first iteration as well as after each iteration.
i is 1 at the start, then print occurs, then i is incremented to 2. Then the condition is evaluated -- it's false, so the loop terminates.
The output is just 1 becuase the do causes the loop to execute at least once, but the condition in the while doesn't aloow the loop to reiterate, because i is never less than 1
It is no more 1
public class DoWhile {
public static void main(String[] args) {
int i = 1; // i is 1
do {
System.out.println("i is : " + i); //still i is 1
i++; // this makes i = 2;
} while(i < 1);
}
}
if you notice the comments it is no more 1 after the first iteration

Categories

Resources