Tracing order of execution in Java - java

I have a factorial code
class FactorialTest {
public static void main(String args[]){
System.out.println(factorial(10));
}
public static int factorial(int N){
if (N <= 1) return 1;
return N*factorial(N-1);
}
}
It was traced using Trace, and this is the output:
Does that mean that recursion part always done first, and the multipication is later?

The recursion must be done first, since it is an argument to the multiplication. Before the recursion gets done, what would even be multiplied?
I don't think your Trace output tells you that, though. I'm answering only after reading the code.

It's possible to implement factorial using tail recursion, but in your code the multiplication follows the recursive call so a tail cail optimization cannot be applied.

Of course the recursive call must be evaluated first. You are multiplying two expressions, one of which is simply a value (N) the other is a recursive call. Without making the call and getting the result first, how would you expect to multiply that to N?

Related

Fibonacci using a recursive method gives me stack overflow

public static int rFib(int n) {
if(n == 0) {
return 0;
}
if(n == 1) {
return 1;
}
return n + rFib(n-1);
}
I am trying to find the largest number that will compute in under 60 seconds. Then I will use an iterative method to compare. Any number greater than 10,000 gives a stack-overflow error. How do I avoid this?
One solution to this recursion problem is to break the recursion using dynamic programming. For example, memoization can be applied and allow you to implement it like
private static Map<Integer, Integer> memo = new HashMap<>();
static {
memo.put(0, 0);
memo.put(1, 1);
}
public static int rFib(int n) {
if (memo.containsKey(n)) {
return memo.get(n);
}
int r = rFib(n - 2) + rFib(n - 1);
memo.put(n, r);
return r;
}
Unfortunately, you have come across the problem which is both the single most-used example for understanding recursion and almost the single worst application to apply recursion to.
It's really simple to understand recursion from the fibonacci because it's a really trivial recursive algorithm for you to explain to somebody and understand... Which means it's great for programming recursion, right? Unfortunately, no.
I apologize if I'm going to tell you things you already know, but I know that fibonacci is one of the first examples in introductory programming so I'm assuming that's where you're coming from.
There's a thing in programming called a stack. It's literally called this because it's like a stack of papers. When you call a function, it puts onto the stack all the information needed to call the function, pass the arguments, and know how to return from the function (and some other administrative stuff). When that function recursively calls itself, it puts another sheet on top of the stack. Then that function puts another sheet. These sheets aren't removed until the function finishes... But since one function can't finish before the other one finishes, it just grows and grows and grows.
And the stack is only so big. Purposely. To avoid this problem.
Normally, recursion isn't used for such deep problems. (Tail-call-recursive people: ignore this; if you don't know what tail-call-recusion is: also ignore this.)
The way to fix this is to not do it. It's generally recognized that in nearly every arbitrarily-recursive function application, a for loop will work better (and faster).

Java Recursion: is saving a variable and then passing to method slower than passing directly

I'm writing a recursive Java algorithm and I'm trying to make it work as fast as possible.
Now I'm facing a dilema since I would like to store some values into variables and would then like to pass the variable to the next recursive call (instead of passing the values directly). This approach would save be a few if statements. However, I'm wondering whether it would also make the program slower because it has to store a variable on every single call.
So I'm wondering whether this simplified problem:
public int Sum(int a) {
if (a==0)
return 0;
int tmp = heavyComputation(a);
return (tmp + Sum(a-1))
is any slower than this:
public int Sum(int a) {
if (a==0)
return 0;
return (heavyComputation(a) + Sum(a-1))
in this simplified example it doesn't really make much difference but in my code, the first approach would save me quite a few ugly if statements.
Thanks!

Differences between System.out.println() and return in Java

I'm trying to understand the difference, and benefits of using System.out.println() vs. return blah in a method.
It seems like System.out.println() is used to display static information, and return is a value returned from the method. Yet I'm seeing examples like the one below, where a function is used within the System.out.println() statement
System.out.println(name.substring(1, 3));
When is it right to use System.out.println() and return. Is it that return can be used by another piece of code later, whereas System.out.println() cannot?
Your last sentence is effectively correct, but the distinction between these two operations is HUGE, so I'd like to provide a more in depth explanation of their differences.
The Difference:
return is an instruction that controls the flow of your program's execution. It is a fundamental part of the Java syntax. It tells the computer what part of your code to execute, and what values to use during that execution. When you return a value, you are saying "The result of calling this method is XXXX" (with 'XXXX' being the value you returned).
System.out.println is not used to control how your program executes. It is a merely way to inform the user of what is going on inside your program. System.out.println (syso for short) can print any information to the console; it doesn't matter if it's a variable, an expression, or the result of a method call. There is no limitation to "static" data.
Let's look at both of them in action:
int addInts(int arg0, int arg1)
{
return arg0 + arg1;
}
This means that wen we call addInts in our program, it will evaluate to the sum of its arguments. So when we write addInts(3, 7), it's the same as if had simply written 3 + 7 or 10 in our source code. Nothing is printed to the console; all we've done is give our program a way of calculating something.
However, any calculations we might make are ultimately useless if all they do is sit inside the computer, so we need a way to display this information to the user. Enter syso:
System.out.println(addInts(22, 16));
The addInts method is called and returns 38. This value is placed somewhere in the computer's memory such that our program can find it.
Next, syso takes that value (38) and prints it to the console, letting the user know what value was calculated. Nothing new is calculated from this procedure, and our program continues to the next statement.
So which do I use?
In simple programs, you have so few values to keep track of that it can be tempting to just print everything that you want to know where you calculate it. For instance, if you were writing a program to do your algebra homework (I've been there) and you wrote a method to solve the quadratic equation, it might be tempting to structure it like this:
class Algebra
{
static void quadSolve(double a, double b, double c)
{
double result = /* do math... we're ignoring the negative result here*/;
System.out.println("The solution to the quadratic equation is: " + result);
}
public static void main(String[] args)
{
quadSolve(1.0, -6.0, 9.0);
}
}
However, this approach quickly becomes a very bad idea if you want to make your program a little more complex. Let's say one problem requires you to solve the quadratic equation and then use the result of that calculation to calculate the volume of a cylinder. In the above example, we can't do that: after we dump the value of result to the console via syso, it disappears when the quadSolve method ends. It would make much more sense if we have quadSolve return result and let the "caller" (the place quadSolve was called from) deal with handling that value. This is a much more flexible design that allows us to make our programs much more complicated with relative ease. This increased flexibility and modularity is really what makes methods useful. Here is the implementation:
class Algebra
{
static double quadSolve(double a, double b, double c)
{
double result = /* do math... we're ignoring the negative result here*/;
return result;
}
public static void main(String[] args)
{
double x = quadSolve(1.0, -6.0, 9.0);
//now we can do whatever we want with result:
//print it, negate it, pass it to another method-- whatever.
System.out.println("The solution to the quadratic equation is: " + x);
System.out.println("And it's square is: " + (x * x));
}
}
I hope this clears things up. Feel free to ask if you need additional clarification.
A method often returns a value (which is done by using the return statement).
Information may be "printed" to an output stream by System.out.println() references.
They both have their uses ... which are usually orthogonal.
They have very little to do with each other.
System.out.println() is used to output strings to a console/terminal. So
System.out.println("Hello world");
should output the string "Hello world"
return is a statement in Java to go back to the code that invoked the method and pass back a value.
public static int add(int a, int b) {
return a + b; // go back to method that called this method (main)
}
public static void main(String[] args) {
int sum = add(3,4); // the return result (7) is stored in sum
}
From my understanding, and to give a simple answer which has a significant meaning, I would say:
It is like when you go to a coffee shop and order a cup of coffee, but the barista tells you if you want a picture of the coffee cup or the cup itself :).
System.out.println() is the picture, while..
return blah is the cup of coffee.
With "return" you can do what you like with the value of return, but with "print" you only see what the function is doing.

Developing a recursive program to calculate an answer

I need to develop a recursive program that can calculate the result 1/i+2/(i-1)+3/(i-2)+…+(i-1)/2+i/1 when f3(1, i) is called.
public class Project4f3
{
public static int f3(int x, int y)
// I know that it has to have a stop termination and i think that is when x==y, but im not sure
if (x==y) return ??
else return f3(x+1,y-1)
// don't think this is right but this is where I am at right now
}
public static void main(String[] args)
{
System.out.print(f3(1,i));
}
}
To develop a recursive algorithm, you need to think about two things:
What are the base cases? These are the cases that can be computed directly. For instance, if n == 1, you can compute the answer directly.
What are the recursive cases? These are the cases that assume that the solution to a reduced problem is available (via a recursive call) and build on that. For instance, if you know the answer for n - 1, how would you use that to compute the answer for n?
Once you've identified those, you are then ready to define and code your recursive method(s).
(I should point out that the n that I'm using here is not necessarily the i you used in your equation. It might make more sense to use the number of terms in the equation as n, or perhaps the number of elements on either side of the middle term. The creative part of recursive problem-solving—and also often the most difficult—is coming up with the right problem representation.)

Getting the number of the order of the function in a recursive call

What is the easiest way to retrieve the order of the function in a recursive call. For instance, if we have a recursive function, it keeps calling itself until it finds the base case, and then it returns one function at a time. The first function returning is of order 0, the second is of order 1, and so on...What is an easy way to retrieve the order information? Say for instance, when it is the function of order three, I would like to do something special.
Edit: I want the function at the top of the stack to be zero.
Edit2: The problem I am trying to solve is to return the nth element of the in order traversal of a binary tree.
If you are starting with a recursive function that looks like this
void recursive(int p1, String p2, long p3) {
...
if (someCondition) {
recursive(nextP1, nextP2, nextP3);
}
}
change it to this:
void recursive(int p1, String p2, long p3, int level) {
...
if (someCondition) {
recursive(nextP1, nextP2, nextP3, level+1);
}
}
Now Start off the level at zero by calling
recursive(initialP1, initialP2, initialP3, 0);
level will indicate the number of invocation of recursive above you.
EDIT : (zero-at-the-top)
You can also transform the function to return its level to implement the "zero at the top" strategy:
int recursive(int p1, String p2, long p3) {
if (baseCase) {
return 0;
}
...
int level = 0;
if (someCondition) {
level = 1+recursive(nextP1, nextP2, nextP3);
}
return level;
}
Note that in this case you cannot find your level until after the last recursive invocation has returned.
The case dasblink has offered you covers the opposite of what you suggested implementation-wise because the level counter rises (increments) as you go deeper in the recursion.
If you want it to decrease as you go deeper in the recursion that would imply that you know the exact recursion depth beforehand.
In most cases if you know the exact recursion depth you won't be using recursion, you'll be using a loop (for, while, repeat/until etc.). In fact using recursion in such a case is less optimal because of the recursion stack that gets allocated (higher memory consumption) and loops are much more efficient.
If the level 0 should be the last "nested call", then it is in general
undecidable problem similar to the halting problem, because you can't
just say "after 3 more nested calls, the function will return a
value". It is possible to look ahead only by simulating the
computation of the particular function.
If the level 0 should be the first call, then it is quite simple and you can use the level as a param of the method and increment it.
btw, interesting problem, see http://en.wikipedia.org/wiki/Halting_problem

Categories

Resources