Related
How do I make a function return the sum of all digits until it becomes a 1 digit number, using recursion? I was able to make a function that gets the sum of all digits, but cant seem to find a way to recursively sum the digits of the sum itself:
class sum_of_digits
{
static int sum_of_digit(int n)
{
if (n == 0)
return 0;
return (n % 10 + sum_of_digit(n / 10));
}
public static void main(String args[])
{
int num = 12345;
int result = sum_of_digit(num);
System.out.println("Sum of digits in " +
num + " is " + result);
}
}
This code prints the sum of '12345', which is 15. But I need to change it so it prints the sum of 1 + 5, which is 6.
do you think it is possible to make it work without an additional
method?
Why can't we just let the recursion do the work for us and simply say:
static int sum_of_digit(int n)
{
if (n < 10)
return n;
return sum_of_digit(n % 10 + sum_of_digit(n / 10));
}
Things will become a lot easier if you define an additional recursive "layer" in conjunction with sum_of_digit. This new function can call sum_of_digit until it has a single digit as a result. Here is what I mean:
static int sum_to_one_digit(int n) {
if(n/10 == 0) return n;
return sum_to_one_digit(sum_of_digit(n));
}
The code from main will be:
public static void main(String args[])
{
int num = 12345;
int result = sum_to_one_digit(num);
System.out.println("Sum of digits in " +
num + " is " + result);
}
You could add a clause at the end to check whether the sum is smaller than 10, if it isn't then recursively call it again with the newly calculated sum, ie.
static int sum_of_digit(int n)
{
if (n == 0)
return 0;
int temp = (n % 10 + sum_of_digit(n / 10));
if (temp < 10)
return temp;
return sum_of_digit(temp);
}
There are several ways to do it, one would be like this if global variables are allowed :
public class Sum_of_digits{
static int sum = 0;
public static void main(String args[]){
int n = 12345;
System.out.println(sum_of_digit(n));
sum = 0;
}
static int sum_of_digit(int n){
if(n==0){
if(sum/10 == 0){
return sum;
}else{
n=sum;
sum=0;
}
}
sum = sum+(n%10);
n=n/10;
return sum_of_digit(n);
}
}
and if Global variable are not allowed then passing sum as a parameter will help :
public class Sum_of_digits{
public static void main(String args[]){
int n = 12345;
int sum = 0;
System.out.println(sum_of_digit(n,sum));
}
static int sum_of_digit(int n,int sum){
if(n==0){
if(sum/10 == 0){
return sum;
}else{
n=sum;
sum=0;
}
}
sum = sum+(n%10);
n=n/10;
return sum_of_digit(n,sum);
}
}
Here we are just shifting the focus from n to sum to evaluate the condition when the loop/recursion will terminate.
I'm trying to create a recursive function that returns the average of the digits in a number. For example the average of the number 123 is 2.
I know how to write a function that sums the digits.
public static int sum (int n) {
if (n<10)
return n;
return n%10 + sum(n/10);
}
I also know how to count the digits
public static int numCount(int n) {
if (n<10)
return 1;
return 1 + numCount(n/10);
}
However I can't figure out how to calculate the average without using pre existing functions.
You can recursively iterate the array while keeping both accumulative sum and an index that shows which items were already iterated:
public class MyClass {
public static void main(String args[]) {
int[] arr = {1,2,3};
System.out.println(avg(arr)); // 2.0
}
private static double avg(int[] arr) {
return avg(arr, 0, 0);
}
private static double avg(int[] arr, int index, int sum) {
if (index == arr.length) {
return (double) sum / index;
}
return avg(arr, index + 1, sum + arr[index]);
}
}
Demo
Try this:
int recursive(int num, int startingSize) {
if(num < 10){
return num;
}
num = num % 10 + recursive(num/10, startingSize++);
return num/startingSize;
}
and for example : recursive(123, 1)
count=0;
public static int sum (int n) {
count++;
if (n<10)
return n;
return n%10 + sum(n/10);
}
double average = (double)sum(123)/count;
System.out.println("average:"+ average);
I mean if we are just talking numbers we don't even need recursive functions here
String s = Double(10.45).toString();
Int size = s.length();
int count = 0;
Int sum = 0;
for (int i = 0; i < size; I++ ) {
try {
sum += Integer.valueOf(s[i]);
++count;
} catch (Exception e) {}
}
return sum / count;
That should give you an. Average regardless of number, whole or real.
I'm trying to implement a binary algorithm but I really don't know how to write this program using a recursion method. Could someone help me please write this method?
I have already written the easiest way for me:
import Prog1Tools.IOTools;
public class BinarySearch {
public static void showArray(int[] array) {
for(int x : array) System.out.print (x + " ");
System.out.println ();
}
public static void fillArray(int[] array, int arrayFirst) {
int i = 0;
while (i < array.length){
array[i] = arrayFirst;
i++;
arrayFirst++;
}
}
public static void main(String[] args) {
int l, p, s;
int arrayEnd = IOTools.readInt("Type a last number in the array : ");
int arrayFirst = IOTools.readInt("Type a first number in the array : ");
int[] nums = new int[arrayEnd+1-arrayFirst ];
fillArray(nums, arrayFirst);
showArray(nums);
System.out.println ("Could you please choose a number from the array above? " );
l = 0;
p = arrayEnd-arrayFirst;
loop: while (l <= p) {
s = (l + p) / 2;
String question = IOTools.readString("Is your number "+nums[s] + " or higher ?[You can answer: yes or higher] ");
switch (question){
case "yes":
System.out.println("I found a number "+nums[s]+" Your number has an index "+s +" in the array");
break loop;
case "higher":
l = s + 1;
break;
}
}
}
}
I tried such method but it doesn't work
public static int recursiveBinarySearch(int[] sortedArray, int start, int end, String question) {
if (start < end) {
int mid = start + (end - start) / 2;
if (question=="higher") {
return recursiveBinarySearch(sortedArray, start, mid, question);
} else if (question=="lower") {
return recursiveBinarySearch(sortedArray, mid+1, end , question);
} else {
return mid;
}
}
return -(start + 1);
}
public boolean binaryS(int A[],int left, int right, int x){
int middle;
//check if there is any array left to search
if (left > right) return false;
//determine the middle of this array section
middle = (left + right) / 2;
//is the middle what we are looking for?
if (A[middle] == x) return true;
//search the half of the array that might contain x
if (A[middle] > x) { //search for x to the left
return binaryS(A, left, middle - 1, x);
} else { //search for x to the right
return binaryS(A, middle + 1, right, x);
}
}
Bob's answer is a nice binary search.
If you want to have user input (and keep your structure):
public static int recursiveBinarySearch(int[] sortedArray, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
String question = IOTools.readString("Is your number compared to "+sortedArray[mid] + " lower or higher?[You can answer: equal, lower or higher] ");
if (question.equals("higher")) {
return recursiveBinarySearch(sortedArray, mid+1, end, question);
} else if (question.equals("lower")) {
return recursiveBinarySearch(sortedArray, start, mid-1, question);
} else {
return mid;
}
}
System.out.println("Something went wrong...");
return -1;
}
For one of the questions i was asked to solve, I found the max value of an array using a for loop, so i tried to find it using recursion and this is what I came up with:
public static int findMax(int[] a, int head, int last) {
int max = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
return findMax(a, head + 1, last);
} else {
return a[head];
}
}
So it works fine and gets the max value, but my question is : is it ok to have for the base case return a[head] and for the case when the value at the head is > the value at last?
You could just as easily do it with only one counter, just the index of the value you want to compare this time:
public static int findMax(int[] a, int index) {
if (index > 0) {
return Math.max(a[index], findMax(a, index-1))
} else {
return a[0];
}
}
This much better shows what is going on, and uses the default "recursion" layout, e.g. with a common base step. Initial call is by doing findMax(a, a.length-1).
It's actually much simpler than that. The base case is if you've reached the end of the array (the 'else' part of the ternary control block below). Otherwise you return the max of the current and the recursive call.
public static int findMax(int[] a) {
return findMax(a, 0);
}
private static int findMax(int[] a, int i) {
return i < a.length
? Math.max(a[i], findMax(a, i + 1))
: Integer.MIN_VALUE;
}
At each element, you return the larger of the current element, and all of the elements with a greater index. Integer.MIN_VALUE will be returned only on empty arrays. This runs in linear time.
I would solve this by dividing the array in to the half on each recursive call.
findMax(int[] data, int a, int b)
where a and b are array indices.
The stop condition is when b - a <= 1, then they are neighbours and the max is max(a,b);
The initial call:
findMax(int[] data, int 0, data.length -1);
This reduces the maximum recursion depth from N to log2(N).
But the search effort still stays O(N).
This would result in
int findMax(int[] data, int a, int b) {
if (b - a <= 1) {
return Math.max(data[a], data[b]);
} else {
int mid = (a+b) /2; // this can overflow for values near Integer.Max: can be solved by a + (b-a) / 2;
int leftMax = findMax(a, mid);
int rightMax = findMax(mid +1, b);
return Math.max(leftMax, rightMax);
}
}
I came across this thread and it helped me a lot. Attached is my complete code in both recursion and divide&conquer cases.
The run time for divide&conquer is slightly better than recursion.
//use divide and conquer.
public int findMaxDivideConquer(int[] arr){
return findMaxDivideConquerHelper(arr, 0, arr.length-1);
}
private int findMaxDivideConquerHelper(int[] arr, int start, int end){
//base case
if(end - start <= 1) return Math.max(arr[start], arr[end]);
//divide
int mid = start + ( end - start )/2;
int leftMax =findMaxDivideConquerHelper(arr, start, mid);
int rightMax =findMaxDivideConquerHelper(arr, mid+1, end);
//conquer
return Math.max( leftMax, rightMax );
}
// use recursion. return the max of the current and recursive call
public int findMaxRec(int[] arr){
return findMaxRec(arr, 0);
}
private int findMaxRec(int[] arr, int i){
if (i == arr.length) {
return Integer.MIN_VALUE;
}
return Math.max(arr[i], findMaxRec(arr, i+1));
}
What about this one ?
public static int maxElement(int[] a, int index, int max) {
int largest = max;
while (index < a.length-1) {
//If current is the first element then override largest
if (index == 0) {
largest = a[0];
}
if (largest < a[index+1]) {
largest = a[index+1];
System.out.println("New Largest : " + largest); //Just to track the change in largest value
}
maxElement(a,index+1,largest);
}
return largest;
}
I know its an old Thread, but maybe this helps!
public static int max(int[] a, int n) {
if(n < 0) {
return Integer.MIN_VALUE;
}
return Math.max(a[n-1], max(a, n - 2));
}
class Test
{
int high;
int arr[];
int n;
Test()
{
n=5;
arr = new int[n];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
high = arr[0];
}
public static void main(String[] args)
{
Test t = new Test();
t.findHigh(0);
t.printHigh();
}
public void printHigh()
{
System.out.println("highest = "+high);
}
public void findHigh(int i)
{
if(i > n-1)
{
return;
}
if(arr[i] > high)
{
high = arr[i];
}
findHigh(i+1);
return;
}
}
You can do it recursively as follows.
Recurrent relation it something like this.
f(a,n) = a[n] if n == size
= f(a,n+1) if n != size
Implementation is as follows.
private static int getMaxRecursive(int[] arr,int pos) {
if(pos == (arr.length-1)) {
return arr[pos];
} else {
return Math.max(arr[pos], getMaxRecursive(arr, pos+1));
}
}
and call will look like this
int maxElement = getMaxRecursive(arr,0);
its not okay!
your code will not find the maximum element in the array, it will only return the element that has a higher value than the elements next to it, to solve this problem,the maximum value element in the range can be passed as argument for the recursive method.
private static int findMax(int[] a, int head, int last,int max) {
if(last == head) {
return max;
}
else if (a[head] > a[last]) {
max = a[head];
return findMax(a, head, last - 1, max);
} else {
max = a[last];
return findMax(a, head + 1, last, max);
}
}
Optimized solution
public class Test1 {
public static int findMax(int[] a, int head, int last) {
int max = 0, max1 = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
max = findMax(a, head + 1, last);
} else
max = findMax(a, head, last - 1);
if (max >= max1) {
max1 = max;
}
return max1;
}
public static void main(String[] args) {
int arr[] = {1001, 0, 2, 1002, 2500, 3, 1000, 7, 5, 100};
int i = findMax(arr, 0, 9);
System.out.println(i);
}
}
Thanks #Robert Columbia for the suggestion!
Update: This following function is going to recursively start from index 0 and it will keep adding to this index value till it's equal to the Length of the array, if it's more we should stop and return 0. Once we're doing that, we need to get the max of every two items in the array so, for example:
A = [1 , 2 , 3 ];
A[0] ( 1 ) vs A[1] ( 2 ) = 2
A[1] ( 2 ) vs A[2] ( 3 ) = 3
Max(2,3) = 3 ( The answer )
public int GetMax(int [] A, int index) {
index += 1;
if (index >= A.Length) return 0;
return Math.Max(A[index], GetMax(A, index + 1));
}
static int maximumOFArray(int[] array,int n) {
int max=Integer.MIN_VALUE;
if(n==1) return array[0];
else
max=maximumOFArray(array, --n);
max= max>array[n] ? max : array[n];
return max;
}
private static int getMax(int [] arr, int idx) {
if (idx==arr.length-1 ) return arr[idx];
return Math.max(arr[idx], getMax (arr,idx+1 ));
}
public class FindMaxArrayNumber {
public static int findByIteration(int[] array) {
int max = array[0];
for (int j : array) {
max = Math.max(j, max);
}
return max;
}
public static int findByRecursion(int[] array, int index) {
return index > 0
? Math.max(array[index], findByRecursion(array, index - 1))
: array[0];
}
public static void main(String[] args) {
int[] array = new int[]{1, 2, 12, 3, 4, 5, 6};
int maxNumberByIteration = findByIteration(array);
int maxNumberByRecursion = findByRecursion(array, array.length - 1);
System.out.println("maxNumberByIteration: " + maxNumberByIteration);
System.out.println("maxNumberByRecursion: " + maxNumberByRecursion);
// Outputs:
// maxNumberByIteration: 12
// maxNumberByRecursion: 12
}
}
int maximum = getMaxValue ( arr[arr.length - 1 ], arr, arr.length - 1 );
public static int getMaxValue ( int max, int arr[], int index )
{
if ( index < 0 )
return max;
if ( max < arr[index] )
max = arr[index];
return getMaxValue ( max, arr, index - 1 );
}
I felt that using a tracker for current maximum value would be good.
I have been using my time off university to practice Java through coding algorithms. One of the algorithms I coded was the binary search:
public class BinarySearch {
private static int list[] = {3, 6, 7, 8, 9, 10};
public static void main(String[] args) {
BinarySearch b = new BinarySearch();
b.binarySearch(list);
}
public void binarySearch(int[] args) {
System.out.println("Binary search.");
int upperBound = args.length;
int lowerBound = 1;
int midpoint = (upperBound + lowerBound) / 2;
int difference = upperBound - lowerBound;
int search = 7;
for (int i = 0; i < args.length; i++) {
if (search < args[midpoint - 1] && difference != 1) {
upperBound = midpoint - 1;
midpoint = upperBound / 2;
} else if (search > args[midpoint - 1] && difference != 1) {
lowerBound = midpoint + 1;
midpoint = (lowerBound + upperBound) / 2;
} else if (search == args[midpoint - 1]) {
midpoint = midpoint - 1;
System.out.println("We found " + search + " at position " + midpoint + " in the list.");
i = args.length;
} else {
System.out.println("We couldn't find " + search + " in the list.");
i = args.length;
}
}
}
}
I really want to be able to write a much cleaner and efficient binary search algorithm, an alternative to what I've coded. I have seen examples of how recursion is used such as when doing factorial with numbers which I understand. However when coding something of this complexity I am confused on how to use it to my advantage. Therefore my question is how do I apply recursion when coding a binary search algorithm. And if you have any tips for me to perfect my recursion skills even if it has to be something that doesn't regard to binary search then please feel free to post.
If you really want to use recursion, this should do it.
public static int binarySearch(int[] a, int target) {
return binarySearch(a, 0, a.length-1, target);
}
public static int binarySearch(int[] a, int start, int end, int target) {
int middle = (start + end) / 2;
if(end < start) {
return -1;
}
if(target==a[middle]) {
return middle;
} else if(target<a[middle]) {
return binarySearch(a, start, middle - 1, target);
} else {
return binarySearch(a, middle + 1, end, target);
}
}
Here is an easier way of doing binary search:
public static int binarySearch(int intToSearch, int[] sortedArray) {
int lower = 0;
int upper = sortedArray.length - 1;
while (lower <= upper) {
int mid = lower + (upper - lower) / 2;
if(intToSearch < sortedArray[mid])
upper = mid - 1;
else if (intToSearch > sortedArray[mid])
lower = mid + 1;
else
return mid;
}
return -1; // Returns -1 if no match is found
}
Following is a code sample extracted from here.
public class BinarySearch {
public boolean find(int[] sortedValues, int value) {
return search(sortedValues, value, 0, sortedValues.length - 1);
}
private boolean search(int[] sorted, int value, int leftIndex, int rightIndex) {
// 1. index check
if (leftIndex > rightIndex) {
return false;
}
// 2. middle index
int middle = (rightIndex + leftIndex) / 2;
// 3. recursive invoke
if (sorted[middle] > value) {
return search(sorted, value, leftIndex, middle - 1);
} else if (sorted[middle] < value) {
return search(sorted, value, middle + 1, rightIndex);
} else {
return true;
}
}
}
You can find implementations of the below test cases against the above binary search implementation as well in the reference link.
1. shouldReturnFalseIfArrayIsEmpty()
2. shouldReturnFalseIfNotFoundInSortedOddArray()
3. shouldReturnFalseIfNotFoundInSortedEvenArray()
4. shouldReturnTrueIfFoundAsFirstInSortedArray()
5. shouldReturnTrueIfFoundAtEndInSortedArray()
6. shouldReturnTrueIfFoundInMiddleInSortedArray()
7. shouldReturnTrueIfFoundAnywhereInSortedArray()
8. shouldReturnFalseIfNotFoundInSortedArray()
A possible example is :
// need extra "helper" method, feed in params
public int binarySearch(int[] a, int x) {
return binarySearch(a, x, 0, a.length - 1);
}
// need extra low and high parameters
private int binarySearch(int[ ] a, int x,
int low, int high) {
if (low > high) return -1;
int mid = (low + high)/2;
if (a[mid] == x) return mid;
else if (a[mid] < x)
return binarySearch(a, x, mid+1, high);
else // last possibility: a[mid] > x
return binarySearch(a, x, low, mid-1);
}
Here you can check in C Binary Search, With and Without Recursion
Source : http://www.cs.utsa.edu/~wagner/CS3343/recursion/binsearch.html
Here is a algorithm which should get you going. Let your method signature be:
public boolean binarysearchRecursion(Array, begin_index,end_index, search_element)
Check if your begin_index > end_index if YES then return false.
Calculate mid_element for your input array.
Check if your search_element is equal to this mid_element. if YES return true
If mid_element > search_element Call your method with for range 0 - mid
If mid_element < search_element Call your method with for range mid+1 - Length_of_Array
Also as #DwB said in his comment you are better using loop to get things done. Some problems are recursive in nature(Like binary tree problems). But this one is not one of them.
This is another way of doing recursion:
int[] n = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
#Test
public void testRecursiveSolution() {
Assert.assertEquals(0, recursiveBinarySearch(1,n));
Assert.assertEquals(15, recursiveBinarySearch(16,n));
Assert.assertEquals(14, recursiveBinarySearch(15,n));
Assert.assertEquals(13, recursiveBinarySearch(14,n));
Assert.assertEquals(12, recursiveBinarySearch(13,n));
Assert.assertEquals(11, recursiveBinarySearch(12,n));
Assert.assertEquals(10, recursiveBinarySearch(11,n));
Assert.assertEquals(9, recursiveBinarySearch(10,n));
Assert.assertEquals(-1, recursiveBinarySearch(100,n));
}
private int recursiveBinarySearch(int n, int[] array) {
if(array.length==1) {
if(array[0]==n) {
return 0;
} else {
return -1;
}
} else {
int mid = (array.length-1)/2;
if(array[mid]==n) {
return mid;
} else if(array[mid]>n) {
return recursiveBinarySearch(n, Arrays.copyOfRange(array, 0, mid));
} else {
int returnIndex = recursiveBinarySearch(n, Arrays.copyOfRange(array, mid+1, array.length));
if(returnIndex>=0) {
return returnIndex+mid+1;
} else {
return returnIndex;
}
}
}
}
While it doesn't return the index, this at least returns the idea of 'yes' or 'no' that something is in the collection:
public static boolean recursive(int[] input, int valueToFind) {
if (input.length == 0) {
return false;
}
int mid = input.length / 2;
if (input[mid] == valueToFind) {
return true;
} else if (input[mid] > valueToFind) {
int[] smallerInput = Arrays.copyOfRange(input, 0, mid);
return recursive(smallerInput, valueToFind);
} else if (input[mid] < valueToFind) {
int[] smallerInput = Arrays.copyOfRange(input, mid+1, input.length);
return recursive(smallerInput, valueToFind);
}
return false;
}
A recursion BinarySearch with break conditions in case you can not find the value you are looking for
public interface Searcher{
public int search(int [] data, int target, int low, int high);
}
The Implementation
public class BinarySearch implements Searcher {
public int search(int[] data, int target, int low, int high) {
//The return variable
int retorno = -1;
if(low > high) return retorno;
int middle = (high + low)/2;
if(target == data[middle]){
retorno = data[middle];
}else if(target < data[middle] && (middle - 1 != high)){
//the (middle - 1 != high) avoids beeing locked inside a never ending recursion loop
retorno = search(data, target, low, middle - 1);
}else if(target > data[middle] && (middle - 1 != low)){
//the (middle - 1 != low) avoids beeing locked inside a never ending recursion loop
retorno = search(data, target, middle - 1, high);
}else if(middle - 1 == low || middle - 1 == high){
//Break condition if you can not find the desired balue
retorno = -1;
}
return retorno;
}
}