Java: About Recursive counting - java

I'm having some problems whit an exercise I found.
I was provided a method, and can't make any changes to it.
Inside said method, I should identify the first repeating digit, beetwen two integers, And return it's position.
For example: 1234 and 4231 results in 1.
And I managed to make it work,
It's just that it doesn't work if I try to use the method more than once, it simply keeps adding to the previous value.
This is my code so far
public static final int BASENUMERACAO = 10;
public static int indice = 0;
private static int getLowestIndexWithSameDigit(int a, int b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException("Both numbers should positive " + a + " " + b);
} else {
if (a % BASENUMERACAO == b % BASENUMERACAO) {
return indice;
} else if (a / BASENUMERACAO != 0 && b / BASENUMERACAO != 0) {
indice++;
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO);
} else {
return -1;
}
}
I tried passing index, as a local variavel, but it just overrides the curent value, everytime it's called, therefore only returning 0 or -1
Could someone tell me how to I do keep count in a recursive method, or just how do I identify the digit whitout a counter?

The problem is that you are retaining state from the previous invocation, in the indice variable. indice is an example of mutable global state, which is generally a bad idea for the reason you are experiencing here: you might carry over the results of previous calculations into new calculations, leading to unpredictable (or maybe unexpected) results.
Make your indice variable a parameter of the method:
private static int getLowestIndexWithSameDigit(int a, int b, int indice) {
// ...
}
So your recursive call will also pass a value for this:
return getLowestIndexWithSameDigit(a / BASENUMERACAO, b / BASENUMERACAO, indice);
To start the iteration, you can either explicitly pass 0, or you can create a method which takes just a and b:
private static int getLowestIndexWithSameDigit(int a, int b) {
return getLowestIndexWithSameDigit(a, b, 0);
}

Create another method to call your recursive method and use the vars that you need as parameter for the recursive version and keep passing them.
Something like:
private static int myMethod( int a, int b ) {
return myRecursiveMethod( a, b, 0, 0 );
}
private static int myRecursiveMethod( int a, int b, int var1, int var2 ) {
// do the recursive work...
myRecursiveMethod( newValueForA, newValueForB, var1, var2 ) {
}

Related

Is this a recursion or not?

I have an argument with my friend because I don't think fib_2() is recursion, but he says it is because it calls itself.
I don't think it is because one fib_2() doesn't have a return result for use as an argument for another fib_2().
I think fib_2() is the same with fib_3(),it's a iteration,not a recursion.
So is it a recursion or not ?
public class Demo {
public static void main(String[] args) {
System.out.printf("fib_1 -> %d\n", fib_1(10));
System.out.printf("fib_2 -> %d\n", fff(10));
System.out.printf("fib_3 -> %d\n", fib_3(10));
}
//This is recursion
public static int fib_1(int n) {
if (n == 1 || n == 2)
return 1;
return fib_1(n - 1) + fib_1(n - 2);
}
//Is this recursion or not ?
public static int fff(int n) {
int a = 1, b = 1, c = 0, count = 2;
return fib_2(a, b, n, c, count);
}
public static int fib_2(int a, int b, int n, int c, int count) {
if (count == n) {
return c;
}
int tmp = b;
b = a + b;
a = tmp;
c = b;
++count;
return fib_2(a, b, n, c, count);
}
public static int fib_3(int n) {
int a = 1, b = 1;
for (int i = 2; i < n; i++) {
int temp = b;
b = a + b;
a = temp;
}
return b;
}
}
fff is not recursive, because it does not calls itself. It calls fib_2 which has a recursive implementation, but it is not enough to make the fff method recursive.
fib_2, on the other hand, is textbook-recursive: it has a base case for count == n, and it has a recursive branch that calls fib_2 with new values of a, b, and c.
fib_2 is recursive. fff is not.
The first call of fib_2 uses returns (hence 'uses') the result of the second call.
Or formal:
Recursion is defined by two properties:
A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer
A set of rules that reduce all other cases toward the base case
Your if inside fib_2 fulfills the first property.
The call to fib_2 fulfills the second.
fib_3 is an iterative.
fib_2 is not equal to fib_3!
Two functions are equal (in a mathematical manner), if and only if they produce the same output for every given input! fib_2 and fib_3 have different parameters so this can't be true.
fib_3 may be equal to fff and/or fib_1
For equality in a computer science manner you have to consider things like side effects.
public static int fib_2(int a, int b, int n, int c, int count) {
if (count == n) {
return c;
}
int tmp = b;
b = a + b;
a = tmp;
c = b;
++count;
return fib_2(a, b, n, c, count);
}
I think in this code recussion is happening.

How does Linear Recursion work?

I have written a java program to add elements in an array using Linear Recursion. The output obtained is not as expected. Can anyone point what is wrong with this program?
public class TestSum {
public int count = 0;
public int sum(int[] a){
count++;
if(a.length == count){
return a[count -1];
}
return sum(a) + a[count -1] ;
}
public static void main(String[] args) {
int[] a = {1,2,3};
int val = new TestSum().sum(a);
System.out.println(val);
}
}
I am expecting the output as 6 but obtained is 9. What is wrong?
Strangely if I change the order of addition i.e. return a[count -1] + sum(a); then it gives output as 6.
Generally, recursive programs that are not re-entrant (i.e. relying on external state) are suspicious. In your particular case count will change between invocations of sum, making the behavior hard to trace, and ultimately resulting in the error that you observe.
You should pass the index along with the array to make it work:
// The actual implementation passes the starting index
private static int sum(int[] a, int start){
if(a.length == start){
return 0;
}
return sum(a, start+1) + a[start];
}
// Make sure the method can be called with an array argument alone
public static int sum(int[] a) {
return sum(a, 0);
}
Unlike an implementation that increments the count external to the method, this implementation can be called concurrently on multiple threads without breaking.

Different ways of using recursion in Java

I'm thinking of several elegant ways of writing a simple Lisp-like recursive function in Java that does, let's say, a simple summation.
In Common Lisp it would be like this:
(defun summation(l)
(if l
(+ (car l) (summation (cdr l)))
0))
(summation '(1 2 3 4 5)) ==> 15
In Java the one of many possible solutions would be:
public int summation(int[] array, int n) {
return (n == 0)
? array[0]
: array[n] + summation(array, n - 1);
}
CALL:
summation(new int[]{1,2,3,4,5}, 4); //15
1) Is there any possible way NOT to use the index n?
2) Or leave your solution (non-iterational) which you see as interesting.
Thanks.
Using Java Collections - something like this should give you an idea of how to eliminate n and recurse in terms of the list size instead:
public int summation( List<Integer> list ) {
return list.isEmpty()
? 0
: list.get( list.size - 1 ) + summation( list.subList( 0 , list.size() - 1 ) );
}
Cheers,
Usually, I solve this kind of recursion with a public API that does not require the index parameter and a private API with any signature I#d like it to be. For this I would separate it this way:
public int summation(int[] numbers) {
return summation(numbers, numbers.length - 1);
}
private int summation(int[] numbers, int till) {
return (till < 0) ? 0 : numbers[till] + summation(numbers, till - 1);
}
Note that you must check till < 0 as this handles an empty array correctly.
Another way would be to not use an array, but any Iterable<Integer>:
public int summation(Iterable<Integer> numbers) {
return summation(numbers.iterator());
}
private int summation(Iterator<Integer> numbers) {
return (numbers.hasNext()) ? numbers.next() + summation(numbers) : 0;
}
Hint: The order of calls in numbers.next() + summation(numbers) is important, as the next() call must be done first.
If you use List.subList method, it may perform iteration, underneath. You can use Queue instead, to avoid iteration. For example:
public int sum(Queue queue) {
return queue.isEmpty() ? 0 : (queue.poll() + sum(queue));
}
public class HelloWorld{
static int sum=0;
static int c;
public static void main(String []args){
int[] y={1,2,3,4,5};
c=y.length;
System.out.println( summation(y)); //15
}
public static int summation(int[] array) {
c--;
if(c<0){
return sum;
}
else{
sum+=array[c];
return summation(array);
}
}
}
Here's a simple method that seems pretty close to what's being asked for.Basically, we are taking a recursive approach to performing summation ascontrasted with brute force from the bottom up.
public static int sumToN(int n) {
if( n == 0 ){
return 0;
}
return n + sumToN(n - 1);
}

Validate variable is in range Java

I have three integers, which are assigned to variables after being passed in as command line parameters. I want to validate that each of the integers are in the range 1-5. Is there a way to accomplish this in Java without using an if statement like the one below? I'd like to avoid doing this (note- pseudocode):
if ((a & b & c) > 0 && (a & b & c) < 6) {
//blah blah
}
Mainly, this wouldn't scale well if additional parameters were added in the future, etc. Is there a more elegant way to accomplish this?
The only improvement I think could be made (for readability) is this:
public boolean isInRange(int i) {
return i > 0 && i < 6;
}
Then call that function instead.
If a, b, and c are related, you may also consider using an array and looping through that. Something like:
public boolean allInRange(int[] arr) {
for (int i = 0; i < arr.length; i ++) {
if (!isInRange(arr[i])) return false;
}
return true;
}
How about something like this:
validate(int ... args) {
for (int arg : args) {
if (arg < 1 || arg > 5) {
throw IllegalArgumentException("Argument is not in valid range [1..5]: " + arg);
}
}
}
and then call this helper method
validate(a,b,c);
You could create a method to which you pass an integer, and the method can return a boolean depending whether or not it is in range.
Another way is to create a method that receives a list of integers List<Integer> myList or an array of integers, and checks each and every one if it is in range.
Here is a faster way to do that without using multiple &&s (for integers only):
private static boolean isInRange(int num, int min, int max) {
return (num - min - Integer.MIN_VALUE) <= (max - (1 - Integer.MIN_VALUE));
}
Usage:
public static void main(String[] args) {
System.out.println(isInRange(5,1,7)); // true
System.out.println(isInRange(5,1,3)); // false
}

Am I understanding passing arguments to functions correctly?

Total noobie question here.
I'm just learning Java, and studying passing arguments to functions. I created this basic example, and it is doing what I expect, but I want to be sure I am understanding the "signal path" correctly:
public void run() {
int value = 4;
println(" the value is "+ add(value));
}
private int add(int n) {
int result = 4;
result = n + result;
return result;
}
}
Am I correct to say that:
1) the int value is being passed from add(value) to the private method and so then int n = 4
2) then the result = n + return. (8)
3) then the return result passes back to the public method and takes the place of add(value).
Is my thinking correct?
Thanks!
Joel
Yes, precisely.
1) the int value is being passed from add(value) to the private method and so then int n = 4
The int value is being passed to the method add(), and then int n will be 4.
2) then the result = n + return. (8)
Yes, that's true. An alternate syntax would be result += n; Which would do the exact same thing.
3) then the return result passes back to the public method and takes the place of add(value).
Yes, then the value is returned from add and that is the value that would be used.
Your thinking is correct.
Yes, this is what parameter passing and value returning is all about. Note that in Java, everything is passed by value.
This means the following:
void f(int x) {
x = 0;
}
void main() {
int n = 10;
f(n);
// n is still 10
}
On (2) that should be "result = n + result", not "n + return". But I think that's just a typo, you appear to understand what's going on.

Categories