how this code execute in compiler? - java

I'm new to Java and I'm reading a couple of books about it.
I can't figure out how the output of this code produced:
import java.util.*;
class myclass {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
System.out.println(factorial(myScanner.nextInt())+"\n");
}
public static int factorial(int n) {
if (n==0) {
return 1;
} else {
int recurse = factorial(n-1);
int result = recurse*n;
return result;
}
}
}
Can anyone please explain this step-by-step for me?
I understand the main method and Scanner class, but I don't understand that when I enter an integer like 8 at input, I get 40320 at output.

Code is easier to work through when you format it properly, so please do that in the future. Sometimes code is also easier to work through when you make it more concise. Notice that you can "inline" the result variable:
public static int factorial(int n) {
if (n == 0) {
return 1;
}
else {
int recurse = factorial(n - 1);
return recurse * n;
}
}
Or more simply:
public static int factorial(int n) {
if (n == 0) {
return 1;
}
return n * factorial(n-1);
}
Now let's try some values. Let's try with the value of "0":
public static int factorial(int n) {
if (n == 0) {
return 1; //<-- Returns 1
}
return n * factorial(n-1);
}
Ok, that's right: 0! = 1.
Let's try with the value of "1":
public static int factorial(int n) {
if (n == 0) {
return 1; //not reached
}
return n * factorial(n-1); //<-- 1 * factorial(0) = 1 * 1 = 1
}
Good: 1! = 1.
Let's try with the value of "8":
public static int factorial(int n) {
if (n == 0) {
return 1; //not reached
}
return n * factorial(n-1); //<-- 8 * factorial(8-1) = 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 40320
}
This makes sense since 8! = 40,320.
The way this is done is called recursion since the method is essentially calling itself. When done well, recursion is a beautiful part of programming since the code is typically fairly concise and is one of a "divide and conquer" mentality. This is an introductory concept in programming.
A good programmer will always be thinking about the system of values. So in this case, your function will provide a StackOverFlow error if n is -1, for example. (You can change the code to read if (n <= 1)).

The function factorial uses recursion to solve the factorial. This means that the function calls itself multiple times, until n becomes 0 (In which it returns 1).
So for n = 3, the program starts by setting the result to
Factorial(3) = factorial(2) * 3,
Factorial(2) = factorial(1) * 2,
Factorial(1) = factorial(0) * 1,
Factorial(0) = 1 (Because of the *if-statement*)
Now you can add the things together, as it knows what Factorial(0), Factorial(1), Factorial(2) and Factorial(3) is.
It then becomes:
Factorial(0) = 1,
Factorial(1) = 1 * 1 = 1,
Factorial(2) = 1 * 2 = 2,
Factorial(3) = 2 * 3 = 6

First of all: Factorial function
I suppose that you don't understand the recursive factorial function.
Declaration of the function:
public static int factorial(int n){
The factorial of 0 is 1 (the exception):
if(n==0){
return 1;
}
If the number introduced by the user isn't 0 then:
else {
int recurse = factorial(n-1);
int result = recurse*n;
return result;
}
In this case, for example, call the function with 2. recurse = factorial(2-1), wait until the call to the function ends (in this case calls to the same function, but it isn't a problem, just wait until the function call ends). Therefore call factorial(2-1). To be continued...
factorial(1), n==0 false, therefore get inside else statement. Call factorial(1-1). Another time wait until the function factorial(1-1) ends. To be continued...
factorial(0), n==0true, therefore return 1. The call to the functions ended, now we will continue the step 2.
Continue factorial(1) in step 2: The factorial(1-1) returns 1 and store it in recurse.int result = recurse * n so result = 1·1. Finally in this step return result (1). Now we go to step 1 that is still waiting in the factorial(1) call.
Continues factorial(2) in step 1: The factorial(2-1) returns 1 ans store it in recurse. int result = recurse * n so result = 1·2. And return result (2).
Finally the factorial(2) returns 2. Think about factorial(3), 4, 5, 6, 7, and finally you will understand factorial 8. The most important thing is that, when you call the same function where you are, it save the state in a stack and wait until it finish.

Related

Why 3 values are printed in console output for powersOf2(int n) program

Problem is when n is 4, it prints 1, 2, and 4
package Example_16;
public class Example {
public static int powersOf2(int n) {
if (n < 1) {
return 0;
} else if (n == 1) {
System.out.println(1);
return 1;
} else {
int prev = powersOf2(n / 2);
int curr = prev * 2;
System.out.println(curr);
return curr;
}
}
public static void main(String[] args) {
powersOf2(4);
}
}
i expect the output to be only 4 and not 1 and 2 ,but console out put shows below which i didn't understand that why 1 and 2 getting printed
$javac Example_16/Example.java
$java -Xmx128M -Xms16M Example_16/Example
1
2
4
When you first call powersOf2(4), n == 4. So you follow the else branch inside the function:
int prev = powersOf2(n / 2);
int curr = prev * 2;
System.out.println(curr);
return curr;
The first thing that happens here is that powersOf2 is called again, with the argument of 2, then of 1. On this third call, n == 1 and so 1 is returned and printed, as in the line System.out.println(1);.
But once that call returns, you're now in the previous call, where the parameter is 2. So now prev = 1, since it was returned. So curr gets set to 2, which is prev * 2. You then print and return curr. This prints 2. When this returns, it is multiplied by 2 and printed and returned again, for a total of 3 prints.
Your code is a recursive program.
On first call to method powersOf2 (from main method) n = 4, it goes to else part of powersOf2 where second call to powersOf2 is made.
On second call to method powersOf2 n =2, it again goes to else part of powersOf2, where third call is made.
On third call to method powersOf2 n = 1, it goes to else if part (n == 1) and print 1 in console.
After that it returns from second call where it prints 2 (in else part) and after that it returns from first call and prints 4 (again in else part).
So you are getting printed 1, 2 and 4.

Remove all numbers except the first using recursion

Basically what I have to do is to remove all digits and leave the first one. If it's a number under 10 keep that number.
I already made some code but instead of removing all digits following the first, I removed the first digit.
My code:
public static int keepFirstDigit(int num) {
// Can't change anything besides the following code
if(num==0){
return 0;
}
if(num>0){
return num % (int) Math.pow(10, (int) Math.log10(num));
}
return num;
}
If the number is 5, the output should be 5.
If the number is 23 the output should be 2.
If the number is 62363456 the output should be 6.
First, you need to understand what is recursion and how it works.
Recursion means function/method call itself.
in below program removeDigit method calling itself if n is greater than 10 with n = n/10.
try this one.
public class Main {
public static void main(String[] args) {
System.out.println(removeDigit(23219));
}
public static int removeDigit(int n) {
if (Math.abs(n) < 10) {
return n;
}
return removeDigit(n/10);
}
}
for n = 23219
iteration 1
23219 > 10
call removeDigit with n = 23219/10 = 2321
iteration 2
2321 > 10
call removeDigit with n = 2321/10 = 232
iteration 3
232 > 10
call removeDigit with n = 232/10 = 23
iteration 4
23 > 10
call removeDigit with n = 23/10 = 2
iteration 5
2 < 10
So return 2
I am not sure if recursion is the best tool to do it however this should work :
public static int keepFirstDigit(int num) {
//Can't change anything besides the following code
if(num < 10) {
return num;
} else {
return keepFirstDigit(num / 10);
}
}
If num is less then 10 we jest return it. Otherwise we divide num by 10 without the remainder and pass it to recursive method call.
For negative numbers we could change the negative number to positive as this does not affect first digit :
public static int keepFirstDigit(int num) {
num = Math.abs(num);
if(num < 10) {
return num;
} else {
return keepFirstDigit(num / 10);
}
}
We could also do the abs before calling this method and pass it as parameter.
I'm not sure if you need to do it recursiveley but if you don't, I'd do it like this
public static int keepFirstDigit(int num) {
String tempNum = String.valueOf(num).substring(0,1);
return((int) Integer.parseInt(tempNum));
}
but if you do, just use the other examples that have already been posted
This can also be achieved using Strings, maybe think of this:
public static int keepFirstDigit(int num) {
//Can't change anything besides the following code
return Integer.parseInt((num+"").charAt(0)+"");
}
Based on #Pankaj Singh and #michalk answer, here is a working, verifiable solution in Javascript.
It also handle negative and null values.
Run it to see output and results.
(Probably not the fastest, shortest way though)
Result for 0 -> 0
Result for 10 -> 1
Result for -10 -> -1
Result for 9.9999 -> 9
Result for 1.57 -> 1
Result for 23 -> 2
Result for 34.5 -> 3
Result for 5678848 -> 5
Result for -3.14159 -> -3
Result for -28.123 -> -2
// Define a function doing the job
// Take an object as argument, not a number (for updating purpose)
const getFirstDigit = (obj) => {
// Ensure argument is valid
if (!obj || !obj.count) {
return;
}
if ((obj.count >= 0 && obj.count < 10)
/* handle negatives */
|| (obj.count <= 0 && obj.count > -10)) {
// Ensure it is an integer
obj.count = parseInt(obj.count);
} else {
// Divide by ten: update obj.count
obj.count = parseInt(obj.count / 10);
// Recursion: call again since number is greater or equals than 10
getFirstDigit(obj);
}
}
// At the end of recursion stack, obj.count will be an integer < 10 == the first digit of initial number
// Give some inputs (and negative values)
let numbers = [0, 10, -10, 9.9999, 1.57, 23, 34.50, 5678848, -3.14159, -28.123];
for (index in numbers) {
let input = numbers[index];
// Prepare an object to hold our number
let object = { count: input };
// Call the method by passing an object
// Passing an object rather a primitive Number allow the function to update the object by reference
getFirstDigit(object)
// Retrieve object updated (or not) number
let output = object.count;
console.log(`Result for ${input} -> ${output}`);
}

Resolving Stacks with Return Statements

Although I think I have a solid understanding of resolving stacks in void methods, return methods really mess up my understanding of stacks. The following method particularly confuses me as I would have thought that it would return 0, but returns 12 instead.
public static int mystery(int n) { // where the method call is mystery(7)
n--; // since n is decremented before the first
// recursive method, the first stack is method(6)
if(n > 0) // base case
mystery(n);
return n * 2; // 0 * 2 = 0?
}
My question is why does the method output 12 when mystery(7), if 0 is the last value to go into the stack. Wouldn't this method still follow LIFO?
This has to be like this:
public static int mystery(int n) { // where the method call is mystery(7)
n--; // since n is decremented before the first
// recursive method, the first stack is method(6)
if(n > 0) // base case
n = mystery(n);
return n * 2; // 0 * 2 = 0?
}
Now it will return 0 always.
From the inside out:
The innermost call to mystery (n is 1 on entry) returns 0 to its caller. The return value is not used.
The next level of mystery (n is 2 on entry) returns 2 to its caller. The return value is not used.
...and so on...
The next-to-outermost level of mystery (n is 6 on entry) returns 10 to its caller. The return value is not used.
The outermost level of mystery (n is 7 on entry) returns 12 to its caller, which is the final return value.
Let's not consider 7. Let's say your value is 3. mystery(3). In this case, the function will run 3 times.
First run:
n = 3;
n--; // n = 2
(n > 0) so mystery(2)
Second run:
n = 2;
n--; // n = 1
(n > 0) so mystery(1)
Third run:
n = 1;
n--; // n = 0
(n = 0) so return the n*2 . And the return will be 4
Why? Cause the recursive function does not change the value of n

Recursive method for a specific sequence

I am trying to get the value of a sequence at a specific position (where the sequence starts at 0). The formula for this sequence is f(n) = (2^n) - 1 where f(0) = 0.
The sequence goes f(0) = 0, f(1) = 1, f(2) = 3, f(3) = 7, f(4) = 15, etc ...
I wrote this recursive function to find the position. However, my numbers are a bit off. Why are my numbers off?
For this result, if I put in the number f(4), I get the value of what is in f(5) -- 31.
public static int getNumber(int num) {
if(num == 0) {
return 1;
} else {
return (int)Math.pow(2,num) + getNumber(num-1);
}
}
I understand that the problem lays within my base case. How can I fix it?
You said f(0) = 0, but your code checks if num == 0, and if it is, returns 1. You just need to return 0 if num == 0.
Although I don't think your recursion will work correctly the way you want it to, either. 2^n - 1 can be expressed as the sum of all powers of 2 less than n, and yours sums up the powers of two less than or equal to n. So you should probably be taking Math.pow(2, num - 1) while you're at it.
Your instructions say f(0) is 0. Also, your function isn't recsursive. I think you wanted 2n - 1 like
public static int getNumber(int num) {
if (num == 0) {
return 0;
}
return (int) (Math.pow(2, num) - 1);
}
I tested it like,
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.printf("f(%d) = %d%n", i, getNumber(i));
}
}
And got your expected results. Of course, you could use a bitshift instead of Math.pow (since it's 2). Like,
public static int getNumber(int num) {
if (num == 0) {
return 0;
}
return (1 << num) - 1;
}
And get the same results.

Euler 14 - Runtime too long (Not really duplicate, I didn't understand how to solve it from similar answer)

So I'm solving Question #14 on ProjectEuler and my code's output is not coming out. The method is good, if I use the example from the website I get the same result BUT I think I get stuck in loop, I don't get a result even if I use a number like "3" or "4" not 1,000,000. What I'm doing wrong? I tried to understand the last question and I didn't really get much with that cache stuff.Here is my code:
import java.util.Arrays;
public class problem_14 {
// n->n/2 (even)
// n->3n+1(odd)
static long max=0;
static long counter = 0;
//Which starting number, under one million, produces the longest chain?
public static long dochain(long n){
while(n!=1){
if(n%2==0){
n=n/2;
counter++;
}
else {
n=(3*n)+1;
counter++;
}
}
counter++;
return counter;
}
public static void main(String args[]){
long chain=0;;
long nr=0;
for(int i=0;i<1000000;i++){
chain = dochain(i);
if (chain>max){
max = chain;
nr = i;
}
System.out.println("nr="+nr+" lungime="+max);
}
}
}
Your dochain() method goes into an infinite loop if you give it a 0.
while (n != 1) {
if (n % 2 == 0) { // true for n == 0
n = n / 2; // n is still 0
counter++;
} else {
n = (3 * n) + 1;
counter++;
}
}
You are checking if it's divisible by 2, which it is, then dividing by 2, which leaves n == 0 and looping forever.
Since your main for loop starts at 0...
You are starting your for loop from i = 0 which is causing dochain() to run infinitely.
Start from i =1.

Categories

Resources