taking an intro CS class on python and was met by this lab on my textbook. It calls for binary search using recursive functions. I have the rest of the program, I simply need to define the Binary Search function. Any help on this would be greatly appreciated.
Here is the problem:
Binary search can be implemented as a recursive algorithm. Each call makes a recursive call on one-half of the list the call received as an argument.
Complete the recursive function binary_search() with the following specifications:
Parameters: a list of integers a target integer lower and upper bounds within which the recursive call will search Return value: if found, the index within the list where the target is located -1 if target is not found The algorithm begins by choosing an index midway between the lower and upper bounds.
If target == nums[index] return index If lower == upper, return lower if target == nums[lower] else -1 to indicate not found Otherwise call the function recursively with half the list as an argument: If nums[index] < target, search the list from index to upper If nums[index] > target, search the list from lower to index The list must be ordered, but duplicates are allowed.
Once the search algorithm works correctly, add the following to binary_search():
Count the number of calls to binary_search(). Count the number of times when the target is compared to an element of the list. Note: lower == upper should not be counted. Hint: Use a global variable to count calls and comparisons.
The input of the program consists of integers on one line followed by a target integer on the second.
The template provides the main program and a helper function that reads a list from input.
Ex: If the input is: 1 2 3 4 5 6 7 8 9 2 the output is:
index: 1, recursions: 2, comparisons: 3
Here is my code:
# TODO: Declare global variables here.
recursions = 0
comparisons = 0
def binary_search(nums, target, lower, upper):
global recursions
global comparisons
if target == nums[(lower upper)/2]:
if lower == upper:
if target == nums[lower]:
return lower
else:
target == -1
elif nums[(lower upper)/2] < target:
recursions = 1
comparisons = 1
binary_search(upper)
elif nums[(lower upper)/2] > target:
recursions = 1
comparisons = 1
binary_search(lower)
if __name__ == '__main__':
# Input a list of nums from the first line of input
nums = [int(n) for n in input().split()]
# Input a target value
target = int(input())
# Start off with default values: full range of list indices
index = binary_search(nums, target, 0, len(nums) - 1)
# Output the index where target was found in nums, and the
# number of recursions and comparisons performed
print(f'index: {index}, recursions: {recursions}, comparisons: {comparisons}')
Error output:
Traceback (most recent call last):
File "main.py", line 34, in <module>
index = binary_search(nums, target, 0, len(nums) - 1)
File "main.py", line 8, in binary_search
if target == nums[(lower upper)/2]:
TypeError: list indices must be integers or slices, not float
CodePudding user response:
Your error means that lower upper
is an odd number, which when you divide by 2 results in something like 3.5, 8.5, etc., which is an invalid index for a list.
To solve this, use floored division (rounding down) with the double slash //
operator
if target == nums[(lower upper)//2]:
CodePudding user response:
Once you've fixed the integer division you'll have a problem when you try to make the recursive call because you're not providing enough parameters.
You may find this helpful:
recursions = 0
comparisons = 0
def binary_search(lst, t):
def _binary_search(lst, lo, hi, t):
global recursions, comparisons
recursions = 1
if hi >= lo:
mid = (hi lo) // 2
comparisons = 1
if lst[mid] == t:
return mid
comparisons = 1
if lst[mid] > t:
return _binary_search(lst, lo, mid - 1, t)
else:
return _binary_search(lst, mid 1, hi, t)
else:
return -1
return _binary_search(lst, 0, len(lst)-1, t)
index = binary_search([1, 2, 3, 4, 5, 6, 7, 8, 9], 2)
print(f'{index=} {recursions=} {comparisons=}')
Output:
index=1 recursions=2 comparisons=3