StackOverflow Error on Java-Cannot see an infinite loop? - java

I am attempting to create a program which finds values which are both "triangle numbers" and "star numbers". However I am slightly confused about when the program branches to the second function etc. Any help is appreciated!
public class Recursion {
public static void main(String[] args) {
// TODO Auto-generated method stub
int count =0;
int n = 1;
int t=0;
int triangularNumber =0;
while (n<Integer.MAX_VALUE)
{
t = isTriangularNumber(n,count,triangularNumber);
triangularNumber=0;
int starNumber= ((6*n)*(n-1)) + 1;
if (starNumber ==t)
{
System.out.println(t);
}
n++;
}
if (n==Integer.MAX_VALUE)
{
System.exit(0);
}
}
public static int isTriangularNumber(int n, int count, int triangularNumber)
{
triangularNumber =triangularNumber + (n-(n-count));
if (count<=n)
{
return isTriangularNumber(n,(count++), triangularNumber);
}
else return triangularNumber;
}
}

return isTriangularNumber(n,(count++), triangularNumber);
In the above invocation, count++ is evaluated to count only. So, on every invocation, you are actually passing unchanged value of count. And hence the if condition: -
if (count<=n)
will always be evaluated to true, if it is true for the first invocation. Thus filling the stack with infinite method invocation.
Your invocation should be with ++count: -
return isTriangularNumber(n,(++count), triangularNumber);

Related

Finding the Base 2 Logarithm of a number using Recursion in java

I'm trying to write a recursive method in Java to find the base 2 log for multiples of 2.
I've successfully computed the log using this recursive method.
import java.util.*;
class temp
{
static int log(int number)
{
if(number==1)
return 0;
return log(number/2)+1;
}
public static void main(String s[])
{
Scanner input=new Scanner(System.in);
System.out.println("Enter Multiple of 2:");
System.out.println("Log is:"+log(input.nextInt())); //calling log with return value of nextInt()
}
}
Where I've run aground is trying to implement the same program using a different method , a method where i start multiplying from 2 in recursive calls until it becomes equal to the given number. Here's what i've tried:
class logarithmrecursion
{
static int step=1;
static int log(int number)
{
final int temp=number;
if(number>=temp && step!=1)
return 0;
step++;
return log(number*2)+1;
}
}
During the first call, number is equal to temp so i use a step variable to prevent the execution of the termination condition.If i don't use "number" variable in the recursive call, i don't have a way to accumulate the previous product but number variable is already equal to temp and will trigger the termination condition in the next recursive call , thus always giving output 1.
What can i do to make this program work?
The first, reducing, version has a fixed termination value of 1.
But the second version's termination depends on the number, so you have to pass that into the recursive call. So, your main function calls a private recursive version:
static int log(int number) {
return log(number, 1);
}
private static int log(int number, int current) {
return current < number ? log(number, current * 2) + 1 : 0;
}
Note: Your algorithm rounds the value up. To give the (more expected) rounded down result, which agrees with (int)(Math.log(i) / Math.log(2)), use this variation:
private static int log(int number, int current) {
return current <= number / 2 ? log(number, current * 2) + 1 : 0;
}
This kind of pattern - using a wrapper function - is common where initial state of the recursion needs to setup once, but we don't want to burden the caller with having to know about what is an implementation choice.
Your first method may also be coded as one line:
static int log(int number) {
return number == 1 ? 0 log(number/2) + 1;
}
try this:
import java.util.Scanner;
public class LogTest
{
static int calLog(final int number)
{
if(number < 2) {
return 0;
}
return log(number, 2, 1);
}
static int log(final int number, final int accumulated, final int step)
{
if(accumulated >= number) {
return step;
}
return log(number, accumulated * 2, step+1);
}
public static void main(String s[])
{
Scanner input=new Scanner(System.in);
System.out.println("Enter Multiple of 2:");
System.out.println("Log is:"+calLog(input.nextInt())); //calling log with return value of nextInt()
}
}

Backtracking is not working for printing all combinations of a string?

I'm trying to print all the permutations of a string. But, despite my best efforts i'm not able to get the required output for my code. Can someone explain me what's wrong with my code? I've been trying this for many hours and failed miserably.
The output for the below code is:-
abc
This is the permute function for backtrack:-
int i, l = 2;
void permute(String str, int n)
{
for(i=n;i<=l;i++)
{
if(n==l)
{
System.out.println(swap(str,n,i));
return;
}
else
permute(swap(str,n,i),n+1);
}
}
This is the main function that runs the above code:-
public static void main(String args[])
{
BacktrackTest bt=new BacktrackTest();
String c="abc";
bt.permute(c,0);
}
This is the code for swap:-
String swap(String st, int s1, int s2)
{
char chr[] = st.toCharArray();
char t;
t = chr[s1];
chr[s1] = chr[s2];
chr[s2] = t;
st = String.valueOf(chr);
return st;
}
Don't define i outside of permute method. Try this:
int l = 2;
void permute(String str, int n)
{
for(int i=n;i<=l;i++)
{
if(n==l)
{
System.out.println(swap(str,n,i));
return;
}
else
permute(swap(str,n,i),n+1);
}
}
If you declare i outside the for loop, it's value is not "restored" for the caller after the return.
In your example, when you enter if(n==l), the value of i is 2, but after you return; it is still 2 because of its global scope. So in the next iteration it gets increased to 3, thus i<=l turns out false and the program ends.
If you declare i it inside the loop, after you return; it will be back at 1 so the loop can continue.

Searching for specific value in array with while-loop

I have the task to build a method to search for an identical value for a variable in an array.
When there is a match, the method will return the index-Position, otherwise it should return -1.
My method works when there is a match, but I get an error when there isnĀ“t any match.
My Code so far:
public class Schleifentest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] cherry = {7,5,6,8,9};
int magNumber = 112;
int enthalten2 = Schleifentest.sucheWhile(cherry, magNumber);
System.out.println(enthalten2);
}
public static int sucheWhile(int [] array, int a) {
int i = 0;
while(i <= array.length) {
if (array[i] == a) {
return i;
}
i++;
}
// here is the problem
return -1;
}
}
Thanks for your help.
Phil
it should be
while(i < array.length) {...}
suppose that the array has 10 elements. They are indexed from 0 to 9. When you reach the end, with your code, you'll consider the one indexed as 10, that doesn't exist, and you have the error.

Correct way to check if a method is invoked recursively

IMPORTANT : THE EXAMPLE IS WRONG, I EXPLAIN WHY AT THE BOTTOM
As the title stated the question is about to define a way to determine when the current executing method is invoked in a recursively way.
I have think about having a "query method" that return a boolean indicating if the invoker method (this is, the method that invokes the "query method") has been already invoked before.
How to check that : just peeking at the stack trace and see if the method we want to check figures two or more times in the stack trace.
Having explaining that, here is the implementation of a method and the respective use of it.
This is not correct...
public class Test
{
public static boolean isRecusivelyInvoqued () {
StackTraceElement[] traces = Thread.currentThread().getStackTrace();
boolean res = false;
// the first belong to "getStackTrace" and the second to "isRecusivelyInvoqued" (this method)
if (traces.length > 2) {
String invokedMethodName = traces[2].getMethodName(); // the third is the method we want to check
for (int i = 3; i < traces.length && !res; i++)
{
res = invokedMethodName.equals(traces[i].getMethodName());
i++;
}
}
return res;
}
// this is a recursive method, used to verify the correct functioning
public static int factorial (int n) {
System.out.println(isRecusivelyInvoqued());
if (n == 0) {
return 1;
}
else {
return n * factorial(n-1);
}
}
public static void main(String[] args)
{
System.out.println(factorial(4));
}
}
I realize if a method in differents namespaces (Class or instance) has the same name, it will return that is invoquedRecursively. I thing that one solution we got this far is that is correct ;) jeje.
This is working for me... is there a better way to archive my goal? How to determine when the current executing method is invoked recursively?
How about this: Your method passes a boolean to the next invocation of the recursive method that tells it that it has been invoked recursively:
public static int factorial (int n) {
return privateFactorial(n, false);
}
private static int privatefactorial(int n, boolean calledRecursively) {
System.out.println(calledRecursively);
if (n == 0) {
return 1;
}
else {
return n * privateFactorial(n-1, true); // tell next invocation here!
}
}
Another option is to add a "is_recursively_invoked" parameter to your recursive function:
public static int factorial (int n, boolean isInvokedRecursively) {
System.out.println(isInvokedRecursively);
if (n == 0) {
return 1;
}
else {
return n * factorial(n-1, true); // these function calls are recursive
}
}
and in your main:
System.out.println(factorial(4, false)); // this function call isn't recursive
If your only goal is to determine if a given method calls itself, then introspect the byte code using any byte code analysis framework and see if there's a call to the method inside the method body.
If you need data about recursion depth then I would use AspectJ (or equivalent) to instrument the method with around advice that can increment a counter. This also eliminates the need for the method itself to do additional work to support your requirement.
That said, I don't understand the need for the requirement; if the method produces the correct answer, and it relies on recursion, then it's using recursion.
You can achieve this using an static boolean variable
Here is a sample:
private static boolean isRecursiveCall = false;
private static int factorial (int n) {
if (n == 0) {
return 1;
}
else {
isRecursiveCall = true;
return n * factorial(n-1);
}
}
public static int findFactorial(int n){
isRecursiveCall = false;
factorial(n);
}
public static void main(String[] args){
findFactorial(2);
}

Fixing a recursive method

I'm trying to write a program that uses recursive method find number of paths from start of two dimension array to the end . The steps should start from [0][0] till the end . Array is filled by int number between 0 to 99 .
For every number in the array can be two different steps forward : for example if [0][0] is 21 , next step could be [0+2][0+1] or [0+1][0+2] .
The method should return number of different paths to get to the final point .
Here is my code :
During the comilation a have overflow when the method gets [][] array
public class two
{
int[][] _my=new int[0][0];
public two ()
{
}
static int count=0;
public static int count;
ountPath(int[][] mat)
{
int nextX=0;
int nextY=0;
int current=mat[0][0];
if (current<=9)
{
nextX=current;
nextY=current;
if (checkBorders(0,0,nextX,nextY,mat)==0)
{
return 0;
}
}
else
{
nextX=(int)current/10;
nextY=current%10;
if (checkBorders(0,0,nextX,nextY,mat)==0)
{
return 0;
}
}
countPath(mat,nextX,nextY);
countPath(mat,nextY,nextX);
return count;
}
public static int countPath(int[][] mat,int x,int y)
{
int current=mat[x][y];
int nextX=0;
int nextY=0;
int terminate=0;
if (current<=9)
{
nextX=current;
nextY=current;
if (checkBorders(x,y,nextX,nextY,mat)==0)
{
return 0;
}
}
else
{
nextX=(int)current/10;
nextY=current%10;
if (checkBorders(x,y,nextX,nextY,mat)==0)
{
return 0;
}
}
if (((mat.length-1)==nextY)&&((mat[0].length-1)==nextX))
{
terminate=1;
}
if (terminate==1)
count++;
else
{
countPath(mat,nextX,nextY);
countPath(mat,nextY,nextX);
}
return count;
}
public static int checkBorders(int x,int y,int x1,int y1,int[][] mat)
{
int maxX=mat[0].length;
int maxY=mat.length;
if ((x+x1)>maxX)
return 0;
else if ((y+y1)>maxY)
return 0;
else return 1;
}
}
Please help me to fix the code.
You have to add one more array of bool where u will store which state have already been visited. Now you may come to following scenario:
You are in state A.
From state A you can go to states B and C.
From state B you can go to state A <- this will be infinite loop.
Also the memorization will increase calculation speed drastically.
Hope I helped you.

Categories

Resources