This question already has answers here:
Binary Search (recursive) [closed]
(3 answers)
Closed 6 years ago.
I need to implement a recursive binary search algorithm for an integer array sorted in ascending order (i.e 1,2,3,4...).
The array I have contains the following numbers:
0 0 0 0 0 0 0 1 2 2 3 3 3 3 5 6 7 7 7 9
However, my current implementation of binary search only finds the numbers to the right of 3. For some reason, it doesn't find 9, 7, 6, and 5.
below is my code:
private int srchHelper(int[] array, int first, int last, int x) {
if (first > last) return - 1;
int mid = (first + last) / 2;
if (array[mid] == x) {
return mid;
}
if (array[mid] < x) {
return srchHelper(array, (mid + 1), last, x);
}
else return srchHelper(array, (mid - 1), last, x);
}
Make sure you're clear about what the algorithm does, and then take a good long look at your recursive calls.
Related
So I was wondering, in my book, recursive binary search is implemented as follows:
private static int bin(int[] arr, int low, int high, int target){
counter++; //ignore this, it was to count how many calls this function invocated
if(low > high) return -1;
else{
int mid = (low+high) / 2;
if(target == arr[mid]) return mid;
else if(target < arr[mid]) return bin(arr, low, mid-1, target);
else return bin(arr, mid + 1, high, target);
}
}
And it says that "If n, the number of elements, is a power of 2, express n as a power of 2... Case 3: The key is not in the array, and its value lies between a[0] and a[n-1]. Here the number of comparisons to determine that the key is not in the array is equal to the exponent. There will be one fewer comparison than in the worst case."
But when I sat down and found the number of function calls using an array {1,2,3,4,5,6,7,9} and key of 8, the number of calls was 4. The book says the number of COMPARISONS is 3 (which is excluding the 3rd line I am guessing?), but I'm pretty sure the number of function calls is 4. I also generalized this to an iterative implementation of binary search and generalized that the number of iterations, OR recursive function calls, is always floor(log base 2 ( n ) ) + 1.
Can explain what's going on here?
Only 3 target == arr[mid] comparisons are made. On the fourth iteration the base case if(low > high) is reached so the comparison is never made. As you stated: "Here the number of comparisons to determine that the key is not in the array is equal to the exponent." You are correct in that we are not dealing with the comparison statement on line 3. We are only concerned with the comparison statement for our target value.
Let's look at the iterations until either of the 2 base cases are reached.
Binary search for 8 in array {1,2,3,4,5,6,7,9}
First iteration:
low = 0
high = 7
mid = 3
arr[mid] = 4
(target == arr[mid]) == false
Second iteration:
low = 4
high = 7
mid = 5
arr[mid] = 6
(target == arr[mid]) == false
Third iteration:
low = 7
high = 7
mid = 7
arr[mid] = 7
(target == arr[mid]) == false
Forth iteration:
low = 8
high = 7
low > high == true
Also, the Big O notation is O(log n). The + 1 is considered insignificant in Big O and therefore not counted. Please see this list on Wikipedia for order of Big O functions from fastest to slowest.
This question already has answers here:
How does recursion work? [closed]
(5 answers)
Closed 5 years ago.
everybody. Need your help. Stuck on the exercise 6.6 from "Think Java" by Downey and Mayfield:
public static void main(String[] args) {
System.out.println(prod(1, 4));
}
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n - 1);
int result = n * recurse;
return result;
}
}
What does exactly prod does? Can you please explain?
I understand that it takes 1 and 4 as arguments and compares at first them between each other. Then since 1 doesn't equal 4 it goes to else and again goes to prod method, this time with arguments 1 and 3. And so on.
I ran the code in the editor with intermediate recurse outputs to see what happens inside prod. Got recurse = 1, recurse = 2, recurse = 6 consequently. But how are they produced?
prod(1, 4)
calls
prod(1, 3)
which calls
prod(1, 2)
which calls
prod(1, 1)
which returns 1
then
prod(1, 2) returns n * recurse, which is 2 * 1 = 2
then
prod(1, 3) returns n * recurse, which is 3 * 2 = 6
then
prod(1, 4) returns n * recurse, which is 4 * 6 = 24
I am doing exercises with algebraic formulas to practice the use of recursion in Java.
I am trying to write a method that returns the result of n + (n - 3) + (n - 6) + (n - 9) ... + 0.
For example, when n = 7, the result should be 12.
When n = 10, the result should be 22.
So far, this is what I have:
public static int sumDownBy3(int n)
{
if(triSum <= 0)
{
return sum;
}
sum = n;
triVar += 3;
triSum = (n - triVar);
return sumDownBy3(n + triSum);
}
However, when I compile and run it, it does not return the expected result.
How may I fix this method to correctly apply the formula I am trying to emulate?
So, here are a few tips to hopefully get you going considering the comments by childofsoong and Jonny Henly.
What you are looking for is simply:
f(n) = n + f(n-3) for n > 0.
Your recursive function should just check if n is <= 0. If it is, return 0. Else return the variable n + another call to your function with n-3.
Hope this helps without giving too much away.
Since this isn't an assignment, just practice, then here is a working solution based off the information given in your question. This solution works for all n, however n <= 0 will always return 0.
public static int sumDownBy3(int n) {
if (n <= 0) {
return 0;
}
return n + sumDownBy3(n - 3);
}
Instead of having an extra parameter or global/class variables keeping track of the sum, this example just uses the stack to keep track of the sum. One downside to this approach is that for a very, very large number the stack could overflow and/or the program could lock up.
Output:
sumDownBy3(7) = 12
sumDownBy3(10) = 22
sumDownBy3(9) = 18
Breakdown for sumDownBy3(10):
sumDownBy3(10): 10 !<= 0 -> return 10 + sumDownBy3(10 - 3)
sumDownBy3( 7): 7 !<= 0 -> return 7 + sumDownBy3( 7 - 3)
sumDownBy3( 4): 4 !<= 0 -> return 4 + sumDownBy3( 4 - 3)
sumDownBy3( 1): 1 !<= 0 -> return 1 + sumDownBy3( 1 - 3)
sumDownBy3(-2): -2 <= 0 -> return 0
So 0 + 1 + 4 + 7 + 10 ='s 22
This question already has answers here:
How to write a recursive method to return the sum of digits in an int?
(13 answers)
Closed 7 years ago.
So I have to write recursive method that adds up value of digits within a certain number. For example, digitSum (1234) returns 10 (which is the sum 1+2+3+4).
So far I have this:
public static int digitSum (int n) {
if(n<10) { return n ;} //basecase
else return !!! ;
}
What should I add in the !!! part, thank you
Just write it in plain english: when you have 1234, initial step should be to do sum(123) + 4
When you convert it to code:
public static int digitSum (int n) {
if(n<10) {
return n
}
else
return n%10 + digitSum(n/10);
}
n%10 gives you the last digit, n/10 gets you the remaining part.
When you have n=1234, n%10 = 4 and n/10 = 123. So according to your plain english sum(123) + 4 it should be digitSum(n/10) + (n%10)
Homework?
1234 remainder 10 is 4, 1234 / 10 is 123 you schould return digitSum(123) + 4
public boolean generateProblems(Integer[] nums, int start) {
if (start == nums.length) {
return false;
}
for (int i = -range; i < range; i++) {
nums[start] = nums[start] + i;
System.out.println(printArray(nums));
Target game = new Target(nums, target);
if (game.solutionSize() == difficulty) {
if (!possibleGames.contains(game.getValues())) {
possibleGames.add(game.getValues());
}
return false;
}
if (generateProblems(nums, start + 1)) {
return true;
}
nums[start] = nums[start] - i;
}
return false;
}
Overview: In the game, 24, you must add, subtract, divide, and multiply four numbers to reach the target, 24. I have a similar, more abstract class called Target, which takes an array of integers and counts (and solves) the solutions to reach a given target value.
I have another class called TargetGenerator which takes a "seed array", a target value, the range, and the number of solutions requested (difficulty). What it should do is call the method, generateProblems, to get a list of possible games such that this combination will only contain difficulty solutions. These possible games are bounded by the initial seed array plus/minus the range. (The seed, {2,3,4,5} with a range 3 is bounded from {-1,0,1,2} up to, but not including, {5,6,7,8}.)
However, the issue I'm having is I have no bloody idea why this isn't working. .Printing out the combinations tried in the console indicates it starts fine, but doesn't end up well.
With a seed of {6,2,3,12}, target of 24, and a range of 3:
2 2 3 12
2 -2 3 12
2 -2 -1 12
2 -2 -1 8
2 -2 -1 9
2 -2 -1 10
A few more lines later is where it messes up...
2 1 1 12
2 1 1 13
2 1 2 10
2 1 2 6
2 1 2 7
2 1 3 7
....Few hundred more combinations later...
9 -1 -23 -46
9 -1 -23 -45
9 -1 -23 -44
9 -1 -23 -43
....And now I'm sad :(
It seems to me there's something wrong with what happens when it reaches the end of the "loop" (when start == nums.length) and it subtracts when it's not supposed to. However, I don't have the debugging know-how to figure out whats wrong.
(I'll give the entire code if any of you want)
I hope it is already not relevant, and you solved it by your self, but if not here what i found wrong with your function. As i understand, you only need to check all posible combinations within given range, if you can reach your target number or not. If so you don't really have to return anything from your generateProblems (you can, but the way you did it just add complexity), you only need to check all your combinations. This is how you can do it :
public void generateProblems(Integer[] nums, int start)
{
if (start != nums.length)
{
for (int i = -range; i < range; i++)
{
nums[start] = nums[start] + i;
action(nums);
generateProblems(nums, start + 1);
nums[start] = nums[start] - i;
}
}
}
Inside the action(nums); goes your logic