I am new to computer science and learning recursion methods. Can someone explain this method briefly?
import java.util.Scanner;
public class factorial {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
System.out.print(factorial(n));
}
private static long factorial(int n) { // HERE I DON'T UNDERSTAND HOW
// THE MACHINE NOWS WHAT IS "factorial"
if (n == 1)
return 1;
else
return n * factorial(n - 1); // ??
}
}
The machine does not know what factorial is, the code there tells it how to calculate a factorial. It does this by saying "Is the number you gave me 1?" and until it is, returns the number times the function return of n - 1, essentially this will cascade into the calculation of a factorial.
This is easily seen if you take an example:
3! = 3*2*1
Or
3! = 3*2!
Which is what the return method gives in the form:
factorial(n) = n * factorial(n-1)
The program given:
factorial(3);
Will go through the following:
Is 3 equal to 1?
It is not so it returns 3*factorial(2)
In order to obtain 3*factorial(2), it calculates factorial(2).
Now it checks: is 2 equal to 1?
It is not so it returns 2*factorial(1), since it is returning to the step three, that overall return will now be 3*2*factorial(1).
Next the program checks: is 1 equal to 1?
It is so it returns 1.
This is returned to our call in step five: 2*factorial(1) becomes 2*1 = 2, which returns to the call from step 3, our first call, giving us 3*2 = 6, which is what the function will return overall.
This method could do with some tweaking though. Imagine you supplied it with 0? It would continuously call the factorial method on an infinite recursion because the sequence 0,-1,-2,-3,-4,... will never reach 1. A better method could look like this:
private static long factorial(int n) {
if (n == 1 || n == 0) {
return 1;
} else if (n < 0) { // factorials are not defined below 0, they can be interpolated
return null; // though, see note below
} else {
return n * factorial(n - 1);
}
}
This function will now cover factorials for the whole range of integers, using a null solution for negative numbers. The definition for a factorial of n is defined as the product of the integers between 1 and n; see this. Factorials of negative integers, floating point numbers, and complex values are also defined or can be interpolated as noted in the link in the previous sentance, but these are much more complex than a simple recursive factorial.
It knows what factorial is because you defined it to be factorial.
You've created a private static long factorial(int n) which means "A method named factorial with a single parameter n that returns a long, is available statically on the factorial class, and is private to that class.
You can call factorial from anywhere that has access to it, which in this case is within the factorial class itself. This means you can call it from the main method, or you can call it from the factorial method itself. It's just a function call that, well, happens to call itself.
We know the definition of factorial, 1 * 2 * ... (n-1) * n. We can also define it as n! = n * (n - 1)! or in other words, factorial(n) = n * factorial(n-1) which is exactly what you see in the last line.
Just take a sheet of paper and trace your code:
factorial(5):
5!=1:
return 5*factorial(4):
4!=1:
return 4*factorial(3):
3!=1:
return 3*factorial(2):
2!=1:
return 2*factorial(1):
1==1:
return 1;
So, at the end we have:
return 5*4*3*2*1 statement
Your code:
private static long factorial(int n) {
if (n == 1)
return 1;
else
return n * factorial(n - 1);
}
defines a method named factorial. It could have been named func, fred, or anything you like; it would not change its behavior.
It's behavior is as follows:
if the argument n is equal to 1, then it simply returns 1
otherwise, it returns the product of n with the result of calling factorial with an argument equal to n - 1. This is the recursive step. Note that the function can call itself and it won't return until the recursive call returns. The chain of calls are pushed onto the stack, each one waiting for the next one to return before it computes the product and returns.
With a little thought, you should be able to see that the above behavior exactly matches a common textbook definition of the factorial function.
Assuming that factorial is called with an argument greater than 0, the recursion will always eventually end with a call to factorial with an argument equal to 1. As written, this function will fail with a stack overflow exception if it is called with a value of n that is less than 1.
It's all about breaking the problem into smaller versions of itself.
What is 1! ?
It's 1.
That's represented by the following code
if (n == 1)
return 1;
Can you find n! if you know (n-1)! ? Of course you can!
Just multiply it by n
represented by the other part of the code.
else
return n * factorial(n - 1);
What you're doing is calling the function from within itself, eventually n will be 1, and the cycle will stop.
The rest of your code is irrelevant, lets break down your recursive function:
private static long factorial(int n) {
if (n == 1)
return 1;
else
return n * factorial(n - 1);
}
What the first line, or signature, says, is "I am a private method (private) that is not attached to a specific object instance (static) that returns a long (which is a long integer value). I'm named 'factorial' because, presumably, the output is the factorial of the input. As input I take an int, which I'm naming n for my purposes.
We know factorials are defined as f(n) = n*(n-1)*...*1. Another way to write this is:
f(n) = n * f(n-1)
Or:
f(n) = n * (n-1) * f(n-2)
f(n) = n * (n-1) * (n-2) * f(n-3)
and so on. But when do you stop? when n == 1. We see this reflected in the method:
if (n == 1)
return 1;//If n == 1, return 1. This is the 'base case'
else
return n * factorial(n - 1);//Multiply n by the factorial of n-1 (duh, right?)
The recursive call here is in that last line: it's using the same function to figure out the solution to a problem that is smaller by a discrete amount. After all, we know that if we multiply n by the result of this smaller problem, we get the correct answer.
Factorial of a number (n=number) is the product of all positive integers less than or equal to n.
factorial of n can denote as n!
ex/
factorial of 5 = 5!
factorial of 100 =100!
factorial of 5 means (5!) -> 5 * 4 * 3 * 2 * 1
ex/ according to this method
1 private static long factorial(int n) {
2 if (n == 1){
3 return 1;
4 } else{
5 return n * factorial(n - 1);
6 }
7 }
if we need to find 5! - (factorial of 5) you have to call the above method using number 5.
ex/
factorial(5)
if (n == 1) condition in line no:2 check the number you pass whether equal to 1 (because 1! is equal to 1) we use this line as our base case(where the place that recursive function stop)
base case
when we call recursion function it keeps calling again and again until our stack becomes overflow. therefore we need a "stopping point" to our recursive function. That endpoint we call as the base case
The main goal is to understand this line-
return n * factorial(n - 1);
in our first iteration n = 5 and n-1 = 4 (according to our example)
Imagine function calls like this
1st iteration 5! = 5 * factorial(4) - inside this line we keep 5 separately and * we call factorial(4) again
2nd iteration 4! = 4 * factorial(3) - inside this line we call factorial(3) again
3rd iteration 3! = 3 * factorial(2) - inside this line we call factorial(2) again
4th iteration 2! = 2 * factorial(1) - inside this line we call factorial(1) again
5th iteration 1! = 1 - start to return 1
Imagine return values like this
ex/
return 5 * factorial(4) -> 5 * [receive (4 * 3* 2* 1)] = 5 * (24)
factorial(4) - 4 * factorial(3) -> 4 * [receive (3 * 2 * 1) = 4 * (6)
factorial(3) -------> 3 * factorial(2) -> 3 * [recieve (2 * 1)] = 3 * (2)
factorial(2) --------------->2 * factorial(1) -> 2 * [return 1] = 1
this image will helpful (image I got from quora.com)
it keeps calling until our n equals to 1
once our function meets the base case which is n=1 it starts to return 1.
(keep in mind until it meets base case it keeps calling the function factorial(n) and until we meet our base case our function do not return anything)
we need to understand how call stack work to understand this.
Let me try explain as per your code :
System.out.print(factorial(n)); /*at this line ,lets assume n=3 ; as soon as we call factorial(3) , this method stores in Stack */
Above line will call method ; private static long factorial(int n) { ... } //n=3
i)it go inside and check if n==1 //false
ii)its goes to else block : 3 * factorial(2) /* again here 3 * factorial(2) will store in stack on top of factorial(3) */
i)it checks again in if n==2 //false
ii)goes to else : 2 * factorial(1) //stores on top of 3 * factorial(2) in stack
i)it checks again in if n==1 // True , this returns value 1.
STACK looks like below in LIFO order:
2 * factorial(1)
3 * factorial(2)
factorial(3)
now question comes where this returned value 1 will go , It will go to top call from stack.
which is ;2 * factorial(1)--> return 2 * 1
value 2 will go to stack of 3 * factorial(2) -- > which 3 * 2 =6
finally value 6 will go to called method : factorial(3).
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n-1)
factorial(4) # = 24
#You can replace code with your prefered language
Here is how it works
If the value less than 2, it is actullay not returing mulitplication of two numbers, instead function returns multiplication of a number and a number return from a function call (n * factorial(n-1))
At last we return 1
Example (Factorial of 4)
Firstly it returns 4 * factorial (3)
Then it returns 4 * 3 * factorial(2)
Then it returns 4 * 3 * 2 * factorial(1). Here the else part of function ends
Then at last it returns 4 * 3 * 2 * 1 = 24
Related
I've been trying to solve this problem for a while, now, but none of my approaches have worked so far.
You're given two linked lists that represents big numbers, where the head of the lists represent the least significant digit.
Return a new list which stores the result of the multiplication of the two lists.
I've tried an algorithm that worked for the first list being a single number, but not more than that.
Initialize a new list.
Initialize a carry.
While node 1 is not null:
While node 2 is not null:
If node 3's next is not null, add it's value to the carry;
Set node 3's next as node 1 * node 2's value + carry.
Set node 2 as it's next, set node 3 as it's next.
End while set at section 4
Set node 1 as node 1's next.
End while set at section 3.
Return list set at section 1.
This obviously has problems. I've also tried to set a "powCounter" for each iteration of the first loop, and multiply the value by 10 to the power of powCounter.
But this didn't work either.
I'd really appreciate any help!
Do it like you would on paper.
Presumably, before tasking you to write multiply(a, b), they would have already had you write add(a, b), right? So use that.
You said you already wrote logic for multiply with a single digit, so let calls that multiplySingle(a, digit).
You need one more helper method, e.g. shiftLeft(a, n), which adds n 0's to the end of the number, i.e. to the beginning of the list. E.g. shiftLeft([4,3,2,1], 2) should return [0,0,4,3,2,1], meaning 1234 * 10² = 123400.
So, on paper you would multiply 123 with 456 like this:
123 * 456
45600 = 1 * 456 * 100 = shiftLeft(multiplySingle([6,5,4], 1), 2)
9120 = 2 * 456 * 10 = shiftLeft(multiplySingle([6,5,4], 2), 1)
1368 = 3 * 456 * 1 = shiftLeft(multiplySingle([6,5,4], 3), 0)
=====
56088 = 45600 + 9120 + 1368 = add(add([0,0,6,5,4], [0,2,1,9]), [8,6,3,1])
Good luck writing the code for that.
FYI: The idea for a shiftLeft() method is based on similar methods in the built-in BigInteger and BigDecimal classes.
BigInteger shiftLeft(int n)
Returns a BigInteger whose value is (this << n). The shift distance, n, may be negative, in which case this method performs a right shift. (Computes floor(this * 2ⁿ).)
BigDecimal movePointRight(int n)
Returns a BigDecimal which is equivalent to this one with the decimal point moved n places to the right. If n is non-negative, the call merely subtracts n from the scale. If n is negative, the call is equivalent to movePointLeft(-n). The BigDecimal returned by this call has value (this × 10ⁿ) and scale max(this.scale()-n, 0).
I am writing a function that determines the number 'n' power sets of a list.
After processing the problem and working through it I found the relationship between the length of the set and the number of powersets.
2^i
where i is the length of the list.
This formula holds true for:
Powers.powers(new int[]{}); // 1
Powers.powers(new int[]{1}); // 2
Powers.powers(new int[]{1,2}); // 4
Powers.powers(new int[]{1,2,3,4}); // 16
Using this information I wrote out the following code:
if(list.length == 1) return BigInteger.valueOf(2);
if(list.length == 0) return BigInteger.valueOf(1);
return BigInteger.valueOf((long)Math.pow(2, list.length));
This works fine for the first few tests, until it hiccups at array length 100. Fortunately it does calculate the correct value that being 1.2676506e+30, but the expected number of powersets of Arraysize 100 is: 9223372036854775807.
Edit:
Adjusted the formula to 2^i, and to clarify I understand how the calculation works, I just don't understand how or why the test case expects 9223372036854775807. It passes an array of length 100 with all values being 0 except for value of index 99 being 100.
You mean 2 ^ n, not 4 ^ (n/2). Well, it's actually the same thing.
And it is very easily calculated with BigInteger, without risk of overflow:
static BigInteger powerSets(int n) {
return BigInteger.ONE.shiftLeft(n);
}
Test
System.out.println(powerSets(0));
System.out.println(powerSets(1));
System.out.println(powerSets(2));
System.out.println(powerSets(4));
System.out.println(powerSets(100));
System.out.println(powerSets(1000));
Output
1
2
4
16
1267650600228229401496703205376
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
UPDATE: If there can be duplicate values, it becomes slightly more complex:
static BigInteger powers(int... values) {
return Arrays.stream(values).boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.values().stream()
.map(freq -> BigInteger.valueOf(freq + 1))
.reduce(BigInteger.ONE, BigInteger::multiply);
}
Test
System.out.println(powers());
System.out.println(powers(1));
System.out.println(powers(1,2));
System.out.println(powers(1,2,3,4));
System.out.println(powers(0,1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,
60,61,62,63,64,65,66,67,68,69,
70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,
90,91,92,93,94,95,96,97,98,99));
System.out.println(powers(1,3,3,3,3,7));
Output
1
2
4
16
1267650600228229401496703205376
20
I was solving the question where we are given a integer and we have to return the greatest power of 10 which is smaller than or equal to the value of given int n.
i tried to solve it but the run time is not as expected.
public int powerofTen(int n){
int x;
if(n>0){
x = 1 + powerofTen(n/10);
}else{
return 0;
}
return x;
}
if i replace last return x , statement with return (int)Math.pow(10,x-1) to get the correct answer the value displayed is 0.
moreover if i try to use return x-1 instead of int x than too it shows 0.
a output for clearance:
if n = 100
with return x value is 3.
with return x-1 value is 0.
with return (int)Math.pow(10,x-1) the value is 0.
This does not have to do with recursion at all, the error is not in recursion code. The problem is that you need your function return e.g:
For input 100 the number 3 and probably return (int)Math.pow(10,x-1). If you replace return x with (int)Math.pow(10,x-1) then you will have wrong result in the recursion calls. For example you will call the function with input 100 which will call the function with input 10 and so on, but you expect the call of the function with input 10 to return to the outer call the value 1. If you place return x-1 (or (int)Math.pow(10,x-1) ) instead of return x then you will take result 0 instead of 1 in the recursion for input 10 and so you will get also 0 for input 100.
The error is logical, in order to solve the problem you need to find the exponent e.g for input 100 the number 3 and then return (outside from the function) (int)Math.pow(10,x-1) .
Even though it's already been replied, this way it's easier to see the steps to do in recursive algortihms:
base case: any number less than 10 returns 0 as greatest exponent for 10
recursive task: add 1 to the greatest exponent found for n/10
Some code:
public int powerofTen(int n){
if(n<10)
return 1;
else
return 10*powerofTen(n/10);
}
I got the following code given:
public class alg
{
public static int hmm (int x)
{
if (x == 1)
{
return 2;
}
return 2*x + hmm(x-1);
}
public static void main (String[] args)
{
int x = Integer.parseInt(args[0]);
System.out.println(hmm(x));
}
}
So first question is, what does this algorithm count?
I have just typed and runned it in eclipse
so I can see better what it does (it was pseudocode before, I couldn't type it here so I typed the code). I have realized that this algorithm does following: It will take the input and multiply it by its following number.
So as examples:
input = 3, output = 12 because 3*4 = 12.
Or Input = 6, output 42 because 6*7 = 42.
Alright, the next question is my problem. I'm asked to analyze the runtime of this algorithm but I have no idea where to start.
I would say, at the beginning, when we define x, we have already got time = 1
The if loop gives time = 1 too I believe.
Last part, return 2x + alg(x-1) should give "something^x" or..?
So in the end we got something like "something^x" + 2, I doubt thats right : /
edit, managed to type pseudocode too :)
Input: Integer x with x > 1
if x = 1 then
return 2;
end if
return 2x + hmm(x-1);
When you have trouble, try to walk through the code with a (small) number.
What does this calculate?
Let's take hmm(3) as an example:
3 != 1, so we calculate 2 * 3 + hmm(3-1). Down a recursion level.
2 != 1, so we calculate 2 * 2 + hmm(2-1). Down a recursion level.
1 == 1, so we return 2. No more recursions, thus hmm(2-1) == hmm(1) == 2.
Back up one recursion level, we get 2 * 2 + hmm(1) = 2 * 2 + 2 = 4 + 2 = 6. Thus hmm(2) = 6
Another level back up, we get 2 * 3 + hmm(2) = 6 + 6 = 12
If you look closely, the algorithm calculates:
2*x + ... + 4 + 2
We can reverse this and factor out 2 and get
2 * (1 + 2 + ... + x).
Which is an arithmetic progression, for which we have a well-known formula (namely x² + x)
How long does it take?
The asymptotic running time is O(n).
There are no loops, so we only have to count the number of recursions. One might be tempted to count the individual steps of calculation, but those a are constant with every step, so we usually combine them into a constant factor k.
What does O(n) mean?
Well ... we make x - 1 recursion steps, decreasing x by 1 in every step until we reach x == 1. From x = n to x = 1 there are n - 1 such steps. We thus need k * (n - 1) operations.
If you think n to be very large, - 1 becomes negligible, so we drop it. We also drop the constant factor, because for large n, O(nk) and O(n) aren't that much different, either.
The function calculates
f(x) = 2(x + x-1 + x-2 + ... + 1)
it will run in O(x), i.e. x times will be called for constant time O(1).
I tried googling this but Google doesn't handle "--n" well. I saw this in my professor's code:
f[--n];
f[n++];
where f is an array of double values.
My guess is that it returns the value of f[n] before reducing (or adding) to n.
f[--n]; means :
n = n -1;
f[n];
f[n++]; means :
f[n];
n = n + 1;
It's actually a type of operator called a pre-decrement, and it's part of a family of 4 operators (see table of java operators)
For an integer-type variable called n:
post-increment n++ is the equivalent of n = n + 1, the 'post' part means that if you see it in a line of code (ex. foo(n++);) then the line of code will be called Before n is incremented.
pre-increment ++n is also the same as n = n + 1 but it occurs Before the line of code it belongs in has been run.
post-decrement n-- is the equivalent of n = n - 1 and occurs After the current line of code has been run
pre-decrement --n is the equivalent of n = n - 1 and occurs Before the current line of code has been run
Example of post vs pre decrement:
int n = 5;
System.out.println(n--); //This prints 5
System.out.println(n); //This prints 4
System.out.println(--n); //This prints 3
System.out.println(n); //this prints 3
you can look it up under predecrement (--n) or postincrement (n++).
It works like this:
f[--n]: first n is reduced by 1 then the value of f[n] (this is already the reduced n) is returned
f[n++]: first the value of f[n] is returned then n is increased by 1
Example:
f {1,3,5}
n=1;
f[--n] returns 1
f[n++] returns 3
The code
f[--n];
f[n++];
Is the same as
n--;
f[n];
f[n];
n++;