Related
class Solution {
int f(int[] a, int s, int n) {
if (n == 0)
return s;
return f(a, s + 1, n - 1) + f(a, s, n - 1);
}
}
class Test {
public static void main(String[] args) {
int[] a = { 1, 1, 2, 3 };
System.out.println(new Solution().f(a, 0, a.length));
}
}
I have written a code to print the number of subset, at every index I got two choices whether to include the a[i] in the subset or not for that I add 1 to s whenever the element is to be included, but this approach gives wrong answer. Why it is wrong?
Math.pow(2, a.length)
would be the obvious solution for that. but if you really want to find it that way it should 'return 1' instead of 'return s' since each time it arrives at zero, it means no element is left, thus empty list, thus 1.
This is what I have so far, but I'm confused on how to keep track of the index. I would change the parameters of the method, but I'm not allowed.
I can only use a loop to make another array. Those are the restrictions.
public class RecursiveFinder {
static int checkedIndex = 0;
static int largest = 0;
public static int largestElement(int[] start){
int length = start.length;
if(start[length-1] > largest){
largest = start[length-1];
int[] newArray = Arrays.copyOf(start, length-1);
largestElement(newArray);
}
else{
return largest;
}
}
/**
* #param args
*/
public static void main(String[] args) {
int[] array1 = {0,3,3643,25,252,25232,3534,25,25235,2523,2426548,765836,7475,35,547,636,367,364,355,2,5,5,5,535};
System.out.println(largestElement(array1));
int[] array2 = {1,2,3,4,5,6,7,8,9};
System.out.println(largestElement(array2));
}
}
Recursive method doesn't need to keep the largest value inside.
2 parameters method
Start to call with:
largestElement(array, array.length-1)
Here is the method:
public static int largestElement(int[] start, int index) {
if (index>0) {
return Math.max(start[index], largestElement(start, index-1))
} else {
return start[0];
}
}
The 3rd line of method is the hardest one to understand. It returns one of two elements, larges of the one of current index and of remaining elements to be checked recursively.
The condition if (index>0) is similar to while-loop. The function is called as long as the index remains positive (reaches elements in the array).
1 parameter method
This one is a bit tricky, because you have to pass the smaller array than in the previous iteration.
public static int largestElement(int[] start) {
if (start.length == 1) {
return start[0];
}
int max = largestElement(Arrays.copyOfRange(start, 1, start.length));
return start[0] > max ? start[0] : max;
}
I hope you do this for the study purposes, actually noone has a need do this in Java.
Try that for the upper class, leave the main method it's is correct.
public class dammm {
public static int largestElement(int[] start){
int largest = start[0];
for(int i = 0; i<start.length; i++) {
if(start[i] > largest){
largest = start[i];
}
}return largest;
}
If your goal is to achieve this by using recursion, this is the code that you need. It is not the most efficient and it is not the best way to deal with the problem but it is probably what you need.
public static int largestElement(int[] start){
int length = start.length;
if (start.lenght == 1){
return start[0];
} else {
int x = largestElement(Arrays.copyOf(start, length-1))
if (x > start[length-1]){
return x;
} else {
return start[length-1];
}
}
}
Imagine that you have a set of numbers you just have to compare one number with the rest of them.
For example, given the set {1,8,5} we just have to check if 5 is larger than the largest of {1,8}. In the same way you have to check if 8 is larger than the largest of {1}. In the next iteration, when the set one have one value, you know that that value is the bigger of the set.
So, you go back to the previous level and check if the returned value (1) is larger than 8. The result (8) is returned to the previous level and is checked against 5. The conclusion is that 8 is the larger value
One parameter, no copying. Tricky thing is, we need to pass a smaller array to the same method. So a global variable is required.
// Number of elements checked so far.
private static int current = -1;
// returns the largest element.
// current should be -1 when user calls this method.
public static int largestElement(int[] array) {
if (array.length > 0) {
boolean resetCurrent = false;
if (current == -1) {
// Initialization
current = 0;
resetCurrent = true;
} else if (current >= array.length - 1) {
// Base case
return array[array.length - 1];
}
try {
int i = current++;
return Math.max(array[i], largestElement(array));
} finally {
if (resetCurrent) {
current = -1;
}
}
}
throw new IllegalArgumentException("Input array is empty.");
}
If you can create another method, everything would be much simpler.
private static int recursiveFindLargest(int [] array, int i) {
if (i > 0) {
return Math.max(array[i], recursiveFindLargest(array, i-1));
} else {
return array[0];
}
}
public static int largestElement(int [] array) {
// For empty array, we cannot return a value to indicate this situation,
//all integer values are possible for non-empty arrays.
if (array.length == 0) throw new IllegalArgumentException();
return recursiveFindLargest(array, array.length - 1);
}
For this problem you really need to think about working with the base case. Take a look at some of the simple cases you would have to deal with:
If the array is length 1, then you return the only value
If the array is length 2, then you return the maximum of the two values
If the array is length 3, then ?
From the above we can get an idea of the structure of the problem:
if array.length == 1 then
return array[0]
else
return the maximum of the values
In the above if we have only one element, it is the maximum value in the list. If we have two values, then we have to find the maximum of those values. From this, we can then use the idea that if we have three values, we can find the maximum of two of them, then compare the maximum with the third value. Expanding this into pseudo code, we can get something like:
if array.length == 1 then
return array[0]
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
return maximum(array[0], largestElement(new array))
To explain the above a little better, think of execution like a chain (example for {1, 2, 3}).
Array: {1, 2, 3}, maximum(array[0] = 1, largestElement(new array = {2, 3}))
Array: {2, 3}, maximum(array[0] = 2, largestElement(new array = {3}))
Array: {3}, array[0] = 3 => length is 1 so return 3
The above then rolls back up the 'tree' structure where we get:
maximum (1, maximum(2, (return 3)))
Once you have the maximum value, you can use the sample principle as above to find the index with a separate method:
indexOf(array, maximum)
if array[0] == maximum then
return 0
else if array.length == 1 then
return -1
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
result = indexOf(new array, maximum)
return (result == -1) ? result : result + 1
For looking into this more, I would read this from the Racket language. In essence it shows the idea of array made purely from pairs and how you can use recursion to do iteration on it.
If you are interested, Racket is a pretty good resource for understanding recursion. You can check out University of Waterloo tutorial on Racket. It can give you a brief introduction to recursion in an easy to understand way, as well as walking you through some examples to understand it better.
You don't need to keep a largest variable outside your method - that's generally not a good practice with recursion which should return all context of the results.
When you think about recursion try to think in terms of a simple base case where the answer is obvious and then, for all other cases how to break it down into a simpler case.
So in pseduo-code your algorithm should be something like:
func largest(int[] array)
if array has 1 element
return that element
else
return the larger of the first element and the result of calling largest(remaining elements)
You could use Math.max for the 'larger' calculation.
It's unfortunate that you can't change the arguments as it would be easier if you could pass the index to start at or use lists and sublists. But your copying method should work fine (assuming efficiency isn't a concern).
An alternative to the algorithm above is to make an empty array the base case. This has the advantage of coping with empty arrays (by return Integer.MIN_VALUE):
int largest(int[] array) {
return array.length == 0
? Integer.MIN_VALUE
: Math.max(array[0], largest(Arrays.copyOfRange(array, 1, array.length)));
}
Here is working example of code with one method param
public int max(int[] list) {
if (list.length == 2) return Math.max(list[0], list[1]);
int max = max(Arrays.copyOfRange(list, 1, list.length));
return list[0] < max ? max : list[0];
}
private static int maxNumber(int[] arr,int n,int max){
if(n<0){
return max;
}
max = Math.max(arr[n],max);
return maxNumber(arr,n-1,max);
}
This question already has answers here:
Reversing a String with Recursion in Java
(17 answers)
Closed 6 years ago.
I'm doing an assignment for a class, but I'm not sure why the code I wrote for these two methods do not work.
For the first method, I'm trying to compare the current position in the array with the next one and if the next one is larger, it becomes the largest. Other wise, the int at the current position becomes the largest. After going through the array with recursive method call, it will return the largest int in the array.
// This method takes an integer array as well as an integer (the starting index) and returns the largest number in the array.
public int largestRec(int[] arr, int pos)
{
// TODO: implement this method
int largest = arr[pos];
if(pos == arr.length-1)
{
return largest;
}
else
{
if(arr[pos] < arr[pos+1])
{
largest = arr[pos+1];
}
else
{
largest = arr[pos];
}
pos++;
largestRec(arr, pos);
}
return largest; // replace this statement with your own return
}
Second method. What I'm trying to do is have it pass a smaller version of the string through a recursive method call and then when the test class calls the method, it will print out the reverse of the string.
// This method reads a string and returns the string in the reversed order.
public String reverseStringRec(String s)
{
// TODO: implement this method
String reverse;
int pos = 0;
if(s=="" || s.length() <= 1)
{
return s;
}
else
{
reverse = reverseStringRec(s.substring(1)) + s.charAt(0);
}
return reverse; // replace this statement with your own return
}
I'm not sure how to write the code to make it do that(for the assignment, I can only modify the methods, not outside variables/methods/classes allowed), so I'd appreciate any advice/help you can offer. If you need more info, I'll be glad to provide it. Thanks.
Edit:
My problem is that the first method does not return the largest. For my test array, it usually prints the first int, or the second one(if it is larger than the first, but does not check the rest). For the second one, my test class(made by my professor), gives the message 'String index out of range" and I don't know how to fix that.
I looked at Jason's suggestion, and put the suggested solution in, but it doesn't seem to be working for my case.
Edit2: The new version of reverseStringRec() now works. Now I need to fix largestRec(). Question is still open if anyone can offer any help.
Edit3: Although I fixed reverseStringRec(), someone gave an answer containing a for loop. I failed to mention that I cannot use loops for this assignment, so I apologize for the inconvenience. I'll put the output of the current largestRec() below if you need to see what results it yields as it is now.
Test 3: largest(10) ==> [Passed]
Expected: 10
Yours: 10
Test 4: largest(10, 20, 30, 40, 50, 60) ==> [Failed]
Expected: 60
Yours: 20
Test 5: largest(70, 20, 30, 40, 50, 10) ==> [Passed]
Expected: 70
Yours: 70
Test 6: largest(70, 20, 100, 40, 50, 10) ==> [Failed]
Expected: 100
Yours: 70
Edit4: Solution found for both methods. For largestRec(), please look at the solutions offered below. For reverseStringRec(), you can use the one in this post or one of the suggested ones below.
Right off the bat, there's a pretty glaring issue with the second method. In it, you recursively call upon the method reverseString, and the argument for that is a substring. However, in this substring, you are attempting to make the substring longer than the original parameter, s - In essence, by including s.length() + 1, the substring() method attempts to create a substring with the character at index s.length() + 1, which does not exist.
For actually reversing the String input to the method, I would highly recommend using the charAt() method.
Check out these methods that find largest number and reverse the strings. Your solutions were pretty close. This is how I would implement these. You needed in index to track the array largest number, otherwise what you can do is pass in the first number and assume its the largest, and every time you find the largest replace it, and once you reach the end of the array you return the largest.
public String reverseString( String str )
{
if(str.length()==1){
return str;
}
return str.charAt( str.length() - 1 ) + reverseString( str.substring( 0, str.length() - 1 ) );
}
// initialize pos to 0
public int getLargest( int[] arr, int pos )
{
int largest = arr[pos];
if ( pos + 1 >= arr.length ) {
return largest;
}
int second = getLargest( arr, pos + 1 );
return largest > second ? largest : second;
}
For reversing a String with a recursive method you can do it this way: public
static String reverseStr(String str) {
if (str.length() == 1)
return str;
else
return str.charAt(str.length()-1) + reverseStr(str.substring(0, str.length()-1));
}
public static void main(String[] args) {
System.out.println(reverseStr("String to be reversed"));
}
Another simple way to reverse a String (not recursive):
public static String reverseStringRec(String s) {
String reverse = "";
int pos = 0;
for (int i = s.length()-1; i >= 0; i--) {
reverse += s.charAt(i);
pos++;
}
return reverse;
}
public static void main(String[] args) {
System.out.println(reverseStringRec("String to be reversed"));
}
For your first part of the question, here is the solution:
static int findMax(int[] arr, int length) {
if (length == 1) {
return arr[0];
}
return max(findMax(arr, length - 1), arr[length - 1]);
}
private static int max(int num1, int num2) {
return num1>num2 ? num1 : num2;
}
public static void main(String[] args) {
int[] arr = {10, 20, 3, 55, 200, 33};
System.out.println(findMax(arr, arr.length));
}
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5 };
int[] b = new int[5];
rekursiq(a, b, 0, 0, 1);
}
static void rekursiq(int[] a, int[] b, int index, int start, int check) {
if (index == b.length){
System.out.println(java.util.Arrays.toString(b));
} else {
for (int i = start; i < a.length; i++) {
b[index] = a[i];
rekursiq(a, b, index + 1, i + 1, check + 1);
}
}
}
Now my question is: Instead of b.length in the recursion bottom I want to place an int check, and make check go +1 on every going there, and do something.
while (check < b.length) go the if statement, else return; but I can't seem to 1) increase the value properly and 2) make this while correctly. I don't know why.
I think my best try was
static void rekursiq(int[] a, int[] b, int index, int start, int check) {
if (check > b.length) {
return;
} else {
if (index == check) {
System.out.println(java.util.Arrays.toString(b));
} else {
for (int i = start; i < a.length; i++) {
b[index] = a[i];
rekursiq(a, b, index + 1, i + 1, check + 1);
}
}
}
}
But it did not work, and I hope some one of you can tell me why and how to fix it.
The value of check does increase when the method is called recursively. However, the problem you have is independent of check.
The Problem
Let me start by repeating what abhishrp already briefly mentioned: In this particular case, you want to either use a loop to iterate over all elements in the array, or recursion, but not use a loop inside of your recursive method. The reason is the following: At each step in the recursion, you look at exactly one element: the element at position index.
The Solution
So, how would you recursively copy an array? Let us assume you have a source array (in your code a) and an empty destination array (in your code b). Now, we know how to copy a single element of the array, namely destination[index] = source[index], and we can imagine copying the array as copying the first element, and then copying the subarray starting at the second element. Note that knowing how to copy a single element in an array implies knowing how to copy an array containing only one element.
This leads us to the following recursion, which we will turn to code shortly after:
if the given index dereferences the last element in the array, then copy this last element.
otherwise, copy the element at the current index, and copy the subarray starting at the next index.
Or expressed in Java:
static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
if (isIndexOfLastElementInArray(index, destination)) {
destination[index] = source[index];
} else {
destination[index] = source[index];
copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
}
}
static boolean isIndexOfLastElementInArray(int index, int[] array){
return index == array.length - 1;
}
Note that you have too many parameters in your code: The parameter check is really just index, as you want to check whether the index is still inside the bounds of the array. I don't really know what you intended to do with the variable start though - seems like somehow you got confused there because of the loop.
Sidenote
Also, a small justification on why the true-branch of the if-statement in the above code does copy the last element instead of returning nothing if the index is out of bounds as in your code. It's perfectly reasonable to do it like you did. The argument "We trivially know how to copy an empty array" just didn't seem as natural as "knowing how to copy a single element implies knowing how to copy an array consisting of a single element". I encourage you however to adjust the code to "copy an empty array" as a base-case, because it removes the duplication, and more importantly, allows you to copy empty arrays (for which the above implementation would fail horribly).
Code
I also tried to give a comparison between the iterative and the recursive approach:
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5};
int[] copyOfAUsingIteration = copyArrayUsingIteration(a);
int[] copyOfAUsingRecursion = copyArrayUsingRecursion(a);
assert(Arrays.equals(copyOfAUsingIteration, copyOfAUsingRecursion));
assert(copyOfAUsingIteration != a);
assert(copyOfAUsingRecursion != a);
System.out.println(java.util.Arrays.toString(copyOfAUsingIteration));
System.out.println(java.util.Arrays.toString(copyOfAUsingRecursion));
}
static int[] copyArrayUsingIteration(int[] arrayToCopy) {
int[] result = new int[arrayToCopy.length];
for(int index = 0; index < result.length; index++){
result[index] = arrayToCopy[index];
}
return result;
}
static int[] copyArrayUsingRecursion(int[] arrayToCopy){
if (arrayToCopy.length == 0){
return new int[0];
} else {
int[] result = new int[arrayToCopy.length];
copyValuesFromSourceToDestinationStartingAtIndex(arrayToCopy, result, 0);
return result;
}
}
static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
if (isIndexOfLastElementInArray(index, destination)) {
destination[index] = source[index];
} else {
destination[index] = source[index];
copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
}
}
static boolean isIndexOfLastElementInArray(int index, int[] array){
return index == array.length - 1;
}
To copy one array to another you can use either iteration or recursion. There is no need to do both. By this I mean there is no need for the for loop inside the rekursiq method.
supposed to reverse an array of strings recursively.
having trouble implementing this. if i was using a for loop i would just start it at the end of the array and print out the array starting with the last element and ending with the first.
I'm not too sure how to do it recursively. i was thinking about using a swap but that idea sort of fizzled when i couldnt figure out how to change the elements that i was swapping.
any ideas or a push in the right direction would be appreciated.
this is what icame up with so far. i know its wrong, i get an error out of bounds exception which im not sure how to fix. I think im not swapping the first and last correctly. but am i getting the right idea?
this is what i came up with.
a is an array. its inside a class.
// reverse an array
public void rev()
{
rev(0,a.length-1);
}
private void rev(int first, int last)
{
if(last == 0)
{
//do nothing
}
else
{
while(first != last)
{
int temp = first;
first = last;
last = temp;
System.out.print(" " + a[first]);
rev((first + 1), (last - 1));
}
}
}
made some changes and it reverses the last 3 elements but the it repeats the second element. i have no if statement that controls when it runs so shouldnt it run until left = right?
this is what i changed it to
// reverse an array
public void rev()
{
rev(0,a.length-1);
}
private void rev(int first, int last)
{
if(last == 0)
{
//do nothing
}
else
{
String temp = a[first];
a[first] = a[last];
a[last] = temp;
System.out.print(" " + a[first]);
rev(first+ 1, last-1);
}
}
The trick with recursion is to try and think of the problem in terms of a base case and then a way to reduce everything to that base case.
So, if you're trying to reverse a list then you can think of it like this:
The reverse of a list of size 1 is that list.
For a list of size > 1 then the first element in the output list will be the last element of the input list.
The rest of the output list will be the reverse of the input list, minus the last element.
You now have your recursive definition.
Hope that helps.
the while loop is too much, since you are using recursion anyway, try it like this
private void rev(int first, int last)
{
if(first < last)
{
var temp = a[first];
a[first] = a[last];
a[last] = temp;
rev(first + 1, last - 1);
}
}
I always like having a simple public method that calls the private recursive one. That way from other places in your code you just give it the array, and don't have to worry about the other arguments. Also, this catches empty arrays, but you would still need to check for null at some point near the start. Maybe throw an exception in the public method if the array is null?
public String[] reverseArray(String[] theArray) {
this.reverseArrayWorker(theArray, 0, theArray.length -1);
}
private String[] reverseArrayWorker(String[] theArray, int left, int right) {
// Check your base cases first
if (theArray.length <= 1) {
// Array is one element or empty
return theArray;
} else if (left - right <= 0) {
// If there are an odd # of items in the list you hit the center
// If there are an even number your indexes past each other
return theArray;
}
// Make the recursive call
this.reverseArrayWorker(theArray, left + 1, right - 1);
// Switch the two elements at this level
String temp = theArray[left];
theArray[left] = theArray[right];
theArray[right] = temp;
// Return the array up a level
return theArray;
}
public int[] reverse(int[] returnMe, int[] original, int curPos){
if (original.length == 1){
return original;
}else{
if (curPos < original.length){
returnMe[curPos] = original[original.length - 1 - curPos];
reverse(returnMe, original, curPos + 1);
}else{
return returnMe;
}
}
}
Here is an example (but without A String since it is homework) but hopefully it will give you the idea.
public static List<Character> reverse(List<Character> chars) {
return chars.isEmpty() ? chars :
addToList(chars.get(0), reverse(chars.subList(1, chars.length()));
}
public static T List<T> addToList(T t, List<T> ts) {
List<T> ret = new ArrayList<T>();
ret.addAll(ts);
ret.add(t);
return ret;
}
This will work too. Kinda Lisp-like solution.
public static List<String> append(String x, List<String> xs) {
xs.add(x);
return xs;
}
public static List<String> reverse(List<String> xs) {
return xs.isEmpty()
? xs
: append(xs.get(0), reverse(xs.subList(1, xs.size())));
}
I/O:
List ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Reversed list ==> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]