我正在尝试编写一个二进制搜索,它将在有序列表中的给定数字之前产生最高数字。
y = int(input("Enter a number:"))
numblist = [5, 8, 9, 10, 18, 20, 25, 28, 30, 35]
lowerval = numblist[0]
higherval = numblist[9]
number = 0
mid = (higherval + lowerval)//2
for y in numblist:
number += 1
if mid == y:
print(number)
break
if mid < y:
lowerval = mid
else:
higherval = mid
mid = (higherval + lowerval)//2
例如,如果我输入20,则返回的数字应为18.我老实说不知道如何拨打正确的位置。我在python非常新,所以任何帮助将不胜感激。
答案 0 :(得分:1)
考虑到你的代码,似乎存在二元搜索的概念问题。如果我们首先处理代码应该更有意义。
什么是二元搜索?
给定一个有序列表,以及您正在搜索的项目,您将列表减半并依次查看每一半。我们来看一个例子吧。给定[1, 2, 3, 4, 5, 6]
并搜索5
,您会看到列表[1,2,3]
和[4,5,6]
的两半。查看上半部分([1,2,3]
),您会注意到最大的项目是3
。鉴于列表是有序的,列表中的所有项目必须小于3
。这意味着5
(您正在搜索的内容)不可能位于较小的列表中。你现在看([4,5,6]
)。让我们把它分成两个列表[4]
和[5,6]
,依此类推。
如何将二进制搜索应用于我的问题
给定一个数字列表和一个搜索词,您需要返回列表中仍然小于搜索词的最大项。
将列表分成两个相等的一半(就像你可以得到它们一样,奇数大小的列表总是不均匀的)。看看下半部分中的最小项目。如果最小项目大于搜索项,那么您知道您要查找的值位于前半部分列表中。否则,它在下半部分列表中。继续拆分列表,直到找到所需内容。
代码是什么样的
def largest_item_less_than_x(x, list_of_vals):
size = len(list_of_vals)
if (size == 0):
return None
if (size == 1):
if (list_of_vals[1] < x):
return list_of_vals[1]
else:
return None
else:
mid = size // 2
left_half_list = list_of_vals[0:mid]
right_half_list = list_of_vals[mid:]
if (right_half_list[0] < x):
return largest_item_less_than_x(x, right_half_list)
else:
return largest_item_less_than_x(x, left_half_list)
让我们一起浏览代码。如果给它一个空列表,则返回None。也就是说,如果没有可供选择的元素,搜索项目不会返回任何内容。
如果你给它一个值大于你要搜索的值的列表,它会返回None,即给定[6]
并搜索3
,你将无法找到你在寻找什么。
如果您为其指定一个值小于您要搜索的值的列表,则会返回该值。
如果你给它一个包含多个项目的列表,那么它会将列表分成两半并递归搜索每一半。
希望这是有道理的。
答案 1 :(得分:0)
以下代码片段可以执行您想要的操作,但方式相对笨拙(但更容易理解):
# Ask the user for an input
y = int(input("Enter a number: "))
# List of numbers to be searched
numblist = [5, 8, 9, 10, 18, 20, 25, 28, 30, 35]
# Set the lower bound of the search
lowerval = numblist[0]
# Set the upper bound of the search
higherval = numblist[-1]
# Search Algorithm
while True:
mid = (lowerval + higherval) // 2
if mid == y:
# Here, I am assuming that you will only test against a list with only unique values.
# It first indexes the value that was found, then subtracts one from it to obtain the value prior to the found value.
print(numblist[numblist.index(y) - 1])
# Then it exits the while loop.
break
if mid < y:
lowerval = mid
if mid > y:
higherval = mid
希望这有帮助!
答案 2 :(得分:0)
此代码可以让您按照自己的要求进行操作,但我不确定用户是否需要输入列表中的数字。
def bin_search(arr,low,high,elem):
mid = (low + high)//2
if low <= high:
# found element or hit end of list
if mid == 0 or mid == len(arr) -1 or arr[mid] < elem and arr[mid+1] >= elem:
print(arr[mid])
return
if arr[mid] < elem:
bin_search(arr,mid+1,high,elem)
else:
bin_search(arr,low,mid-1,elem)
y = int(input("Enter a number: "))
numblist = [5, 8, 9, 10, 18, 20, 25, 28, 30, 35]
lowerval = numblist[0]
higherval = numblist[-1]
# special cases
# highest value is smaller
if higherval < y:
print(higherval)
# no such value is larger
elif lowerval > y:
print("-1")
else:
bin_search(numblist,0,len(numblist)-1,y)
答案 3 :(得分:0)
您的代码存在一些问题。首先,您将覆盖for循环语句中的输入变量y
。其次,代码没有在for循环中正确缩进(可能只是你帖子中的错误?)。
获取二进制搜索的一些提示:
numblist
开始。检查数字是否相等,大于或小于并相应地继续。 这是一个简单的代码,概述了我的建议并且似乎有效。可能不是最终答案,但应该有所帮助。
y = int(input("Enter a number:"))
numblist = [5, 8, 9, 10, 18, 20, 25, 28, 30, 35]
found = False
while not found:
print numblist
mid = len(numblist)/2 # integer div in python 2
if (y == numblist[mid]):
found = True
x = numblist[mid - 1]
elif len(numblist) == 1:
found = True
x = numblist[0]
elif y < numblist[mid]:
# search in the lower half
numblist = numblist[0:mid]
else:
# Search in the upper half
numblist = numblist[mid:]
print x
答案 4 :(得分:0)
有一个问题,您的列表是否真的按升序排列?无论我认为你能做到什么,
y = int(input("Enter a number:"))
numblist = [5, 8, 9, 10, 18, 20, 25, 28, 30, 35]
tempNum = 0
index = 0
tempIndex = 0
for nums in numblist:
tempIndex++
if nums != y:
if nums > tempNum:
tempNum = nums
index = tempIndex
else:
break
print(tempNum)
print(numblist[index])
所以这会循环你的numblist的每个索引。然后它会询问当前事件是否等于您输入的数字。如果是,它退出循环,如果不是,则它比较先前和当前发生的数量。找到您在列表中输入的数字后,它会退出循环。在最后一个语句中,您可以打印在发生事件发生之前包含最大数字的tempNum,或者在其列表中索引最大数字的numblist。希望你能理解我的英语。
答案 5 :(得分:0)
这是一个二元搜索的递归算法,用于在// Test cases
[
'1',
'12',
'123',
'1234',
'12345',
'123456',
'1234567',
'12345678',
'123456789',
'1234567890',
'1.23',
'1.234',
'1.2345',
'1.234567890',
'1234567890.1234567890',
'1+2-3+4',
'12+34-56+78',
'123+456-789',
'1234+5678',
'12345-678',
'1234567-8',
'-123456.7890',
'1+2-3456.7890',
'1+2-3456.7890+123456789-0.1234'
].forEach(function(str) {
var out = str.replace(/(?:^|[^\.\d])\d+/g, function(match) {
return match.replace(/(\d)(?=(\d\d\d)+$)/g, '$1,');
});
console.log(out);
});
中查找小于 x
的元素的索引:
arr
请注意,如果该值小于列表
中的第一个值,则会返回def binary_search_lessthan(x, arr, offset=0):
arr = sorted(arr)
ix = len(arr)//2
if x==arr[ix]:
return ix+offset-1
elif x<arr[ix]:
if len(arr)==1:
return offset-1
return binary_search_previous(x, arr[:ix], offset)
elif x>arr[ix]:
if len(arr)==1:
return offset
return binary_search_previous(x, arr[ix:], offset+ix)
-1