Factorial recursion Exception not given in java 1.6 - java

Why I am not getting any Exception in the following code?
After running this code I am getting an infinite loop mentioning at test.fact(t.java:32)
No Compile-Time Error was found.
class test
{
int fact(int m) throws Exception
{
if (m==1)
{
return 1;
}
else
return (fact ((m-1)*m));
}
}
class main
{
public static void main(String ar[]) throws Exception
{
test t = new test();
System.out.println(t.fact(5));
}
}
while say for example i am using
return(a+b);
it executes successfully whats the problem with the recursion
to show an error???

You have a mistake in the return value expression of fact method.
It should be
return fact(m-1) * m;

Another way to calculate factorial using cycle (with no recursion):
int fact(int m) throws Exception
{
int f = 1;
for (int i = 0; i < m; f *= ++i);
return f;
}

return (fact ((m-1)*m));
returns
fact(20)
which returns
fact (380)
which returns
fact (379*380)
which ....
which never returns anything and should make a stack overflow (too much memory is used on the call stack).
return fact(m-1) * m;
should work.
I highly recommend you reading again the basics, and examples ( here, for example - http://www.toves.org/books/java/ch18-recurex/index.html)
Try writing the recursion tree yoursels, in order to understand what happens.

Related

Multiplication in Java using recursion

I am new to programming and I am writing a simple code in Java that is using recursion. I want to show the product of two numbers (from start to End). The return of the method is the multiplication of the numbers from start to end. (For Example: If the numbers are 1 and 3 then I want the method to return 6.
I managed to do the recursion but I am not sure if the code is effective at all. Here is my code so far. Thanks
public class ÜbungsblattSieben {
public static void main(String[] args) {
System.out.println(multiplyFromStartToEnd(1, 3));
}
public static int multiplyFromStartToEnd(int start, int end) {
if (start == end) {
return end;
} else {
return start * multiplyFromStartToEnd(++start, end);
}
}
}
Your code is as effective as a recursive multiplication can be. Well done.
That said, here are a few notes:
You may write start + 1 instead of ++start. Generally easier to read and understand. Also you do not have to change the start variable itself, you just want to pass a bigger number to the method call, thats all.
You may also want to properly indent your code (just hit the auto-format key in your IDE).
I would also suggest to rename your method to multiplyFromTo, but thats a very subjective note.
All in all, your code would then look like:
public class ÜbungsblattSieben {
public static void main (String[] args) {
System.out.println(multiplyFromStartToEnd(1, 3));
}
public static int multiplyFromTo(int start, int end) {
if (start == end) {
return end;
} else {
return start * multiplyFromStartToEnd(start + 1, end);
}
}
}
For reference, here is how an iterative version could look like:
int result = 1;
for (int i = start; i <= end; i++) {
result *= i;
}
System.out.println(result);
Obviously, this is a lot faster than recursion.

Set variable value in method under test in Junit

How can we set value of some integer variable in a method under test in Junit? This is just a made up code to reproduce the problem I have. Here is the code:
void someMethod(long l) {
int i = 0;
while (i < l) {
if (i == Integer.MAX_VALUE) {
throw new RuntimeException;
}
i++;
}
I need to set i to 2,147,483,647 in test to check that when the if condition is true, it properly throws the exception.
First of all, my question was not descriptive of the problem that i had.
I was able to create an instance variable
int maxVal = Integer.MAX_VALUE
So, the method looked like this:
void someMethod(long l) {
int i = 0;
while (i < l) {
if (i == maxVal) {
throw new RuntimeException;
}
i++;
}...
and then set the instance variable to a different value at the test case, 0 in case of the code above, and it threw exception like i had wanted.
Thanks Turing85 for that clue.
You can pass argument long l to be Integer.MAX_VALUE+1 this will allow i to be equal to Integer.MAX_VALUE and you will get exception thrown.

Turning a for loop to recursive method for prime numbers

I need to convert the code below to a recursive method without using global variables and using only one parameter.I Searched the topics already there is no code with one parameter and doesnt use the global variables.
public boolean isPrime(int x){
for(int i=2;i<x;i++)
if(x%i==0) return false ;
return true;
}
Ok, as for your requirements:
Without using global variables.
Using only one parameter.
And, based on:
it come up in one of my university exams
There a couple of aspects to take into account:
If you pass an instance of a Class you are passing only one variable, and as Classes can have multiple variables inside...
They do not state if you can call multiple functions inside, so, again, this is a hint or clue, of what can you do. So, two solutions for you:
Solution 1 (Using Classes)
class RecursVar {
int x;
int i = 2;
RecursVar(int x) {
this.x = x;
}
}
public boolean isPrimeRecurs(int x){
return isPrime(new RecursVar(x));
}
boolean isPrime(RecursVar recursVar) {
if(recursVar.x % recursVar.i == 0)
return false;
if (++recursVar.i >= recursVar.x)
return true;
return isPrime(recursVar);
}
Solution 2 (Cleaner approach without using Classes but based in that the function that can have only one parameter is isPrime )
boolean isPrime(int x) {
return checkForPrime(x, 2);
}
boolean checkForPrime(int x, int i) {
if (i >= x) return true;
if (x % i == 0) return false;
return checkForPrime(x, ++i);
}
Again, this solutions are based on that many exams require a little creativity and maybe that was the aim of this case.
This cases should not be used in production, they are slow and
prune to make honor to this site (StackOverFlow) with a sweet
java.lang.StackOverflowError
It's an interesting problem.
If you can use java 8, you can solve the problem as followed (note that the case isPrime(2) needs to be checked with an additional if condition):
package test;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
System.out.println(isPrime(13));
}
private static Function<Integer, Boolean> fun;
public static boolean isPrime(int x) {
fun = i -> {
if (i > 2) return (x%i != 0) && fun.apply(i-1);
else return (x%i != 0);
};
return fun.apply(x-1);
}
}
One of my schoolmates' topic accually recieve a solution here it is if you interested its quite brilliant
https://stackoverflow.com/questions/35660562/finding-prime-numbers-recursively-with-using-only-one-parameter?noredirect=1#comment59001671_35660562

Why doesn't this return a new value over and over? java

public static int someFunc(int a, int b){
while(a <=b){
a+= 1;
return a;
}
return b;
}
so i was expecting it to return the new value over and over but it didnt, once i executed the code and saw for myself that, i realised it had something to do with pass by value or by reference which is something i dont really understand! can someone explain?
The immediate problem is that return returns! Nothing after it can be executed. You can't have a meaningful loop with an unconditional return in it.
As far as the other, no. That's not the issue as you return the new value of a. The a you passed in remains unchanged which is the pass by reference/value you speak of. Java is pass by value.
public class JHelp {
public static void main(String...args) {
JHelp j = new JHelp();
int a = 1;
System.out.print(j.f(a));
System.out.print(a);
}
int f(int a ) {
a += 1;
return a;
}
}
Will give you an output of:
21
because the return instruction exits the code hence the methods done its job it doenst need to iterate again once it reaches the return instruction, i however would have done it if the return instruction wasnt reached.

what's the reason for stackoverflow exception in this?

import java.math.BigInteger;
import java.util.HashMap;
/**
*
* #author cypronmaya
*/
public class test {
static HashMap<Integer, BigInteger> cache = new HashMap<Integer, BigInteger>();
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
BigInteger ret;
if (n == 0) {
return BigInteger.ONE;
}
if (null != (ret = cache.get(n))) {
return ret;
}
ret = BigInteger.valueOf(n).multiply(factorial(n - 1));
cache.put(n, ret);
return ret;
}
}
Exception in thread "main" java.lang.StackOverflowError at
java.util.HashMap.get(Unknown Source)
Hi,
Why am i getting stackoverflow exception to this program?
i know that stackoverflow usually means you have an infinite loop,
but this works fine when i'm using 10000 or some other numbers lesser, wht becomes suddenly infinite with big numbers?
A StackOverflowError occurs when the call stack overflows. This happens when you have too many nested calls (because each call requires space to be reserved on the stack, and it's a finite size). I guess in your case, 20000 is too many.
You can modify the stack size of the JVM with the -Xss flag. But I'd suggest that you find a different way to compute a factorial.
The recursive function each time that is called create a new pointer in the stack, so with an high number of calls of a recursive function you can get a StackOverflow Exception ...
Tip : replace the recursive function with a loop to resolve.
The reason is that your factorial function is recursive and this is NOT tail recursion.
It means that every time you call the "factorial" function this call is put to the stack.
I have no idea if Java compiler can generate tail recursion calls at all, but if it can, you can simply refactor your function to a tail-call way. Otherwise just avoid recursion (a good practice in imperative languages anyway).
Non-recursive versions (not so much as compiled - this is Stack Overflow). There will be clearer ways to write this.
public class Test {
private static final Object lock = new Object();
private static final List<BigInteger> cache = new ArrayList<>(
Arrays.asList(BigInteger.ONE)
);
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
synchronized (lock) {
int r = cache.size();
if (n < r) {
return cache.get(n);
}
BigInteger current = cache.get(r-1);
for (;;) {
current = BigInteger.valueOf(r).multiply(current);
cache.add(current);
if (n == r) {
return current;
}
++r;
}
}
}
}
You can resize the Java default stack size runtime with the -Xss switch
eg: java -Xss2048k YourClass

Categories

Resources