I need to write a recursive method which looks through an array and finds the smallest index, however I am having a bizarre issue, for some reason my given test array seems to return a result of 10. I have tried debugging in eclipse and something very odd happens, my findMinAux method does indeed find -10 to be the smallest value and when I press the "step into" button it does seem as if it is about to return -10 but then it goes into some weird loop and startIndex starts increasing for some reason. If anyone has any advice as to where I am going wrong it would be greatly appreciated, thank you.
Here is my code:
public class Q1 {
public static void main(String[] args) {
int[] testArr = {12,32,45,435,-1,345,0,564,-10,234,25};
findMin(testArr);
}
public static int findMin(int[] arr) {
int result = findMinAux(arr,arr.length-1,arr.length-1);
System.out.println(result);
return result;
}
public static int findMinAux(int[] arr, int startIndex, int smallest) {
if(arr[startIndex]<smallest) {
smallest = arr[startIndex];
}
startIndex--;
if(startIndex>=0) {
findMinAux(arr,startIndex,smallest);
}
return smallest;
}
}
Two problems:
First, you should initiate smallest with the last element if you want to search from the end of array:
int result = findMinAux(arr,arr.length-1,arr[arr.length - 1]);
Secondly, you should reassign smallest:
if(startIndex>=0) {
smallest = findMinAux(arr,startIndex,smallest);
}
class Minimum {
int minelem;
int minindex;
Minimum() {
minelem = Integer.MAX_VALUE;
minindex = -1;
}
}
public class Q1 {
public static void main(String[] args) {
int[] testArr = {12,32,45,435,-1,345,0,564,-10,234,25};
findMin(testArr);
}
public static int findMin(int[] arr) {
Minimum m = new Minimum();
m = findMinAux(arr,arr.length-1,m);
System.out.println(m.minindex);
return m.minindex;
}
public static Minimum findMinAux(int[] arr, int lastindex, Minimum m) {
if(lastindex < 0) {
return m;
}
if(m.minelem > arr[lastindex]) {
m.minelem = arr[lastindex];
m.minindex = lastindex;
}
return findMinAux(arr,lastindex - 1, m);
}
}
I have used another class here for simplification. Please check if this solved your problem meanwhile I am explaining why and how it is working.
Actually, this implementation works fine
public static int findMinAux(int[] arr, int startIndex, int smallest) {
if(startIndex < 0)
return smallest;
if(arr[startIndex] < smallest){
smallest = arr[startIndex];
}
return findMinAux(arr, startIndex - 1, smallest);
}
And also you has a typo in calling this funtion, the last parameter must be an value from array, in your case the last value, not the last index.
int result = findMinAux(arr,arr.length-1, arr.length - 1);
change to
int result = findMinAux(arr,arr.length-2, arr[arr.length - 1]);
This approach works with a single method and an overloaded version so you don't have to pass the initial values
public static int findMin(int[] arr) {
int index = 0;
int min = Integer.MAX_VALUE;
min = Math.min(arr[index], min);
return findMin(arr,index+1,min);
}
private static int findMin(int[] arr, int index, int min) {
if(index < arr.length)
{
min = Math.min(arr[index], min);
return findMin(arr,index+1,min);
}
System.out.println(min);
return min;
}
The second method is private so from outside the class, only the first/default method can be called.
See this code. In every iteration, elements are compared with current element and index in increased on the basis of comparison. This is tail recursive as well. So it can be used in large arrays as well.
public class Q1 {
public static void main(String[] args) {
int[] testArr = {12, 32, 45, 435, -1, 345, 0, 564, -10, 234, 25};
System.out.println();
System.out.println(find(testArr, 0, testArr.length - 1, testArr[0]));
}
public static int find(int[] arr, int currPos, int lastPos, int elem) {
if (currPos == lastPos) {
return elem;
} else {
if (elem < arr[currPos]) {
return find(arr, currPos + 1, lastPos, elem);
} else {
return find(arr, currPos + 1, lastPos, arr[currPos]);
}
}
}
}
Related
I have a program that I'm trying to make for class that returns the sum of all the integers in an array using recursion. Here is my program thus far:
public class SumOfArray {
private int[] a;
private int n;
private int result;
public int sumOfArray(int[] a) {
this.a = a;
n = a.length;
if (n == 0) // base case
result = 0;
else
result = a[n] + sumOfArray(a[n-1]);
return result;
} // End SumOfArray method
} // End SumOfArray Class
But I'm getting three error which are all related, I believe, but I can't figure out why it is finding a type of null:
SumOfArray.java:25: sumOfArray(int[]) in SumOfArray cannot be applied to (int)
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: operator + cannot be applied to int,sumOfArray
result = a[n] + sumOfArray(a[n-1]);
^
SumOfArray.java:25: incompatible types
found : <nulltype>
required: int
result = a[n] + sumOfArray(a[n-1]);
^
3 errors
The solution is simpler than it looks, try this (assuming an array with non-zero length):
public int sumOfArray(int[] a, int n) {
if (n == 0)
return a[n];
else
return a[n] + sumOfArray(a, n-1);
}
Call it like this:
int[] a = { 1, 2, 3, 4, 5 };
int sum = sumOfArray(a, a.length-1);
The issue is that a[n-1] is an int, whereas sumOfArray expects an array of int.
Hint: you can simplify things by making sumOfArray take the array and the starting (or ending) index.
a[n-1]
is getting the int at n-1, not the array from 0 to n-1.
try using
Arrays.copyOf(a, a.length-1);
instead
How about this recursive solution? You make a smaller sub-array which contains elements from the second to the end. This recursion continues until the array size becomes 1.
import java.util.Arrays;
public class Sum {
public static void main(String[] args){
int[] arr = {1,2,3,4,5};
System.out.println(sum(arr)); // 15
}
public static int sum(int[] array){
if(array.length == 1){
return array[0];
}
int[] subArr = Arrays.copyOfRange(array, 1, array.length);
return array[0] + sum(subArr);
}
}
a is an int array. Thus a[n-1] is an int. You are passing an int to sumOfArray which expects an array and not an int.
Try this if you don't want to pass the length of the array :
private static int sumOfArray(int[] array) {
if (1 == array.length) {
return array[array.length - 1];
}
return array[0] + sumOfArray(Arrays.copyOfRange(array, 1, array.length));
}
Offcourse you need to check if the array is empty or not.
This is the one recursive solution with complexity O(N).and with input parameter A[] only.
You can handle null and empty(0 length) case specifically as Its returning 0 in this solution. You throw Exception as well in this case.
/*
* Complexity is O(N)
*/
public int recursiveSum2(int A[])
{
if(A == null || A.length==0)
{
return 0;
}
else
{
return recursiveSum2Internal(A,A.length-1);
}
}
private int recursiveSum2Internal(int A[],int length)
{
if(length ==0 )
{
return A[length];
}
else
{
return A[length]+recursiveSum2Internal(A, length-1);
}
}
without any predefined function.
public static int sum(int input[]) {
int n = input.length;
if (n == 0) // base case
return 0;
int small[]=new int[n-1];
for(int i=1;i<n;i++)
{
small[i-1]=input[i];
}
return input[0]+sum(small);
}
private static int sum(int[] arr) {
// TODO Auto-generated method stub
int n = arr.length;
if(n==1)
{
return arr[n-1];
}
int ans = arr[0]+sum(Arrays.copyOf(arr, n-1));
return ans;
}
Simplified version:
//acc -> result accumlator, len - current length of array
public static int sum(int[] arr, int len, int acc) {
return len == 0 ? acc : sum(arr, len-1, arr[len-1]+ acc);
}
public static void main(String[] args) {
int[] arr= { 5, 1, 6, 2};
System.out.println(sum(arr, arr.length, 0));
}
public class TestForMatch2
{
public static void main(String[] args)
{
int[] numbers1 = {0,2,4,6,7,11,0};
int[] numbers2 = {-7,5,9,10,5,0};
System.out.println(findTarget(numbers1,5));
System.out.println(findTarget(numbers1,0));
System.out.println(findTarget(numbers2,5));
System.out.println(findTarget(numbers1,-1));
}
public static int findTarget(int[] arr, int target)
{
if (arr == null) {
return -1;
}
int y = 0;
int g = 0;
for(int i = 0; i <= arr.length-1; i++) {
if (target == arr[i]) {
y = i;
//return y;
}
}
System.out.println(y);
return -1;
}
}
Output:
0
-1
6
-1
4
-1
0
-1
As you can see, there is a -1 that is being printed. If I remove the return -1, it gives me an error. How to remove the -1 without the error?
This is what is to be done.
Write a Java method to test if an array of integers contains a specific value.
If the value is in the array, returns the index of the element. If the value is more than once the method will return the index of the last occurrence of the value.
If the value is not in the array, returns -1.
Copy and paste the following code. Then complete the method.
public class Main
{
public static void main(String[] args)
{
int[] numbers1 = {0,2,4,6,7,11,0};
int[] numbers2 = {-7,5,9,10,5,0};
System.out.println(findTarget(numbers1,5));
System.out.println(findTarget(numbers1,0));
System.out.println(findTarget(numbers2,5));
System.out.println(findTarget(numbers1,-1));
}
public static int findTarget(int[] arr, int target)
{
//Type your code here
}
}
This is the desired result. Ignore the numbers on the left. I put it there to emphasise on the space on number 5. Thank you for your time.
1 -1
2 6
3 4
4 -1
5
public static void main(String[] args)
{
int[] numbers1 = {0,2,4,6,7,11,0};
int[] numbers2 = {-7,5,9,10,5,0};
System.out.println(findTarget(numbers1,5));
System.out.println(findTarget(numbers1,0));
System.out.println(findTarget(numbers2,5));
System.out.println(findTarget(numbers1,-1));
}
public static int findTarget(int[] arr, int target)
{
if (arr == null) {
return -1;
}
int targetIndex = -1;
for(int i = 0; i <= arr.length-1; i++) {
if (target == arr[i]) {
targetIndex = i;
}
}
return targetIndex;
}
Create a variable targetIndex which will keep the index of the target element, initially it is -1, if we find target element at index i, then our targetIndex becomes i, then we return it.
Here is the solution.
public static void main(String[] args)
{
int[] numbers1 = {0,2,4,6,7,11,0};
int[] numbers2 = {-7,5,9,10,5,0};
System.out.println(findTarget(numbers1,5));
System.out.println(findTarget(numbers1,0));
System.out.println(findTarget(numbers2,5));
System.out.println(findTarget(numbers1,-1));
}
public static int findTarget(int[] arr, int target)
{
int index = -1;
if(null != arr) {
for(int i=0;i<arr.length;i++) {
if(arr[i] == target) {
index = i;
}
}
}
return index;
}
You did System.out twice per iteration. Do you know why?
You always print what y is - first System.out():
System.out.println(y);
Then you always return -1:
return -1;
What gets printed too - second System.out():
System.out.println(findTarget(numbers1,5));
You said: "If I remove the return -1, it gives me an error.".
--> You have to return an integer, since your method says "public static int findTarget(int[] arr, int target)". So it compiles if you return -1, since -1 is an integer, but also if you return y, because you also assigned an integer to y.
So change the findTarget() to the following:
public static int findTarget(int[] arr, int target)
{
if (arr == null) {
return -1;
}
int y = -1;
for(int i = 0; i <= arr.length-1; i++) {
if (target == arr[i]) {
y = i;
}
}
return y;
}
Initialize y = -1 and return y, you're returning -1 no matter what you feed into the function.
This is a homework assignment and I'm having trouble figuring out what I'm doing wrong. I am supposed to write a method that returns the max int from an array of ints without using a loop or any other methods such as Math.max etc. I wrote a method that can do it with a while loop but I am having trouble figuring out what is wrong with my recursive search. I keep getting 0 when doing the recursive search.
public class RecursiveGetMax {
public static void main(String[] args) {
int [] arr = {1,3,7,5,4};
System.out.println("The max int using a loop is: " + loopMax(arr,0));
System.out.println("The max int using a recursive search is: " + recursiveMax(arr,0));
}
public static int loopMax(int[] arr, int index) {
int ret = 0;
int maxSoFar = 0;
while (index < arr.length-1) {
if(arr[index] >= maxSoFar) {
maxSoFar = arr[index];
}
++index;
}
if (index == arr.length-1) {
ret = maxSoFar;
}
return ret;
}
public static int recursiveMax(int[]arr, int index) {
int maxSoFar = 0;
int ret = 0;
if (index > arr.length-1) {
ret = maxSoFar;
}
else {
if (arr[index] >= maxSoFar){
maxSoFar = arr[index];
}
recursiveMax(arr,index + 1);
}
return ret;
}
}
try this code
The main problem was then maxSoFar was getting overwritten and your recursive call did not return its value
static int maxSoFar = Integer.MIN_VALUE; // set to a very small number
public static void main (String [] args) throws Exception
{
int [] arr = {1,3,7,5,4};
System.out.println("The max int using a recursive search is: " + recursiveMax(arr,0)); // pass it in
}
public static int recursiveMax(int[]arr, int index) {
if (index > arr.length-1) {
return maxSoFar;
}
else {
if (arr[index] >= maxSoFar){
maxSoFar = arr[index];
}
return recursiveMax(arr,index + 1);
}
}
Edit
Changed to use static variable due to OP's comments
look at the max function..
public class Snippet {
public static void main(String[] args) {
int arr[] = {3,5,6,2,8,6,5,1};
System.out.println(max(arr, 1, arr[0]));
}
public static int max(int arr[], int i, int max){
if(i < arr.length){
max = Math.max(arr[i], max);
return max(arr, i+1, max);
}
return max;
}
}
the key point is you need to carry all require data, while recurse
I'm trying to recursively find two elements in an array with the smallest difference (assume the array is already sorted in an increasing order).
I've been trying to get my code to just return the smallest sum, but something seems to be not working right with the recursion.
public class SmallestDiff {
public static void main (String [] args){
int [] x = {1,3,6,9,126};
System.out.println(smallestDiff(x,4));
}
public static int smallestDiff (int [] array, int index){
int result;
if (index>0){
int diff = Math.abs((array[index]-array[index-1]));
result = Math.min (diff, smallestDiff(array,index-1));
}
else {
return array[0];
}
return result;
}
}
Your mistake is
return array[0];
array[0] is not a difference between values so should not be returned. The simplest way to fix your program is to replace this line with
return array[1] - array[0];
Try this :
public class SmallestDiff {
public static void main(String[] args) {
int[] x = { 1, 3, 6, 9, 126 };
int result;
if (x.length < 2) {
result = x[0];
}
else{
result = smallestDiff(x, x.length-1);
}
System.out.println(result);
}
public static int smallestDiff(int[] array, int index) {
if (index == 0) {
return Integer.MAX_VALUE;
}
int diff = (array[index] - array[index - 1]);
return Math.min(diff, smallestDiff(array, index - 1));
}
}
This solution prints the first element in case there is only one element in the array. Otherwise, it will always result the smallest difference between two elements.
If your array is sorted no need for recursion.
The code below solves the problem with iteration.
public class SmallestDiff {
public static void main(String[] args) {
int[] x = {1, 3, 6, 9, 126};
System.out.println(smallestDiff(x));
}
public static int smallestDiff(int[] array) {
int result = Integer.MAX_VALUE;
for (int i = 0; i < array.length - 1; i++) {
int diff = Math.abs((array[i] - array[i + 1]));
if (diff < result) {
result = diff;
}
}
return result;
}
}
Ths is a question from a past paper. I have been asked to create a static method arrayMin to find the smallest value in the array arr.
I have to use a while loop and on each iteration, the variable min will return the smallest number from the first i elements.
Is there a way to do this without calling another method/for loop and strictly using the while loop, as the question is only worth 4%(including writing loop invariants and javadoc). Not sure if I am overcomplicating the problem.
public class Revision {
public static int arr[] = new int[] { 5, 8, 4, 3, 6, 2 };
public static int min = 1;
public static int arrayMin() {
int i = 0;
if (arr == null) {
return 0;
} else {
while (i < arr.length) {
// some function/method call to find smallest number of arr[i]
i++;
return min;
}
}
return min;
}
public static void main(String[] args) {
System.out.println(arrayMin());
}
}
A couple of things:
The array shouldn't be static, you should pass it as a parameter to the arrayMin method;
min should be a local arrayMin variable, not static;
min should be initialized to Integer.MAX_VALUE. If you initialize it with 1, and 2 happens to be the min value of the array, you'll never return it;
You can't return multiple times from a method. As soon as you do return min, the method ends. There's probably some confusion over the the variable min will return the smallest number from the first i elements phrase. It probably means that in each iteration, the variable min will have (not return) the smallest number from the first i elements.
Here's a refactor:
public static int arrayMin(int[] arr) {
int i = 0;
int min = Integer.MAX_VALUE;
if (arr == null) {
return 0; // What if 0 is the minimum value? What do you want to do in this case?
} else {
while (i < arr.length) {
if (arr[i] < min) {
min = arr[i];
}
i++;
}
}
return min;
}
You need to have a variable outside of the loop called min. You will use the loop to find the minimum of the array, and return min when the loop is complete.
} else {
int min = Integer.MAX_VALUE;
while(i < arr.length) {
// is arr[i] < min? If so, it's the new minimum
i++;
}
return min;
}
multiple ways to do it, but here is one.
public static int arrayMin(int[] arr) {
boolean isFirstElement = true;
int smallestNumber= 0;
int index = 0;
while(index < arr.length) {
int temp= arr[index];
index++;
if (isFirstElement) {
smallestNumber = temp;
isFirstElement = false;
} else if (smallestNumber > temp) {
smallestNumber = temp;
}
}
}
You can use a index variable to keep in track of the number of positive hits and if the corresponding numbers index value is one lesser the array size, that number is the smallest
class testtt{
static int small=0;
public static void main(String[] args) {
int arr[] = {9,2,3,4,5,6,7,8};
int i,index=0;
for(int q:arr)
{
for(i=0;i<arr.length;i++)
{
if(q<arr[i])
{
small=q;
index++;
}
}
if(index==arr.length-1)
System.out.println(small);
}
}
}