【发布时间】:2014-08-30 05:15:03
【问题描述】:
我编写了一个搜索算法,它在排序列表中找到一个字符串,然后在两边的条目中搜索重复项。
import re
found = []
missing = []
def find_media(media, drive_inv):
"""
media is a string.
drive_inv is a list of strings.
use binary search to find a match,
followed by a linear seach either side
to check for duplicates.
append a match to the global list, found.
else append to the global list, missing.
"""
def linear_search_up(media, line):
""" line is an int, to index drive_inv with. """
try:
if re.search(media, drive_inv[line+1], re.IGNORECASE):
found.append(drive_inv[line+1])
return linear_search_up(media, line+1)
else:
return
except IndexError:
return
def linear_search_down(media, line):
""" line is an int, to index drive_inv with. """
try:
if re.search(media, drive_inv[line-1], re.IGNORECASE):
found.append(drive_inv[line-1])
return linear_search_down(media, line-1)
else:
return
except IndexError:
return
def binary_search(media, low, high):
"""
low and high are ints - the boundries of the
binary search algorithm.
if a match is found, execute the linear seach
function on the entries either side.
"""
if high == low:
if re.search(media, drive_inv[low], re.IGNORECASE):
found.append(drive_inv[low])
return
else:
missing.append(media)
return
mid = (low + high) / 2
if re.search(media, drive_inv[mid], re.IGNORECASE):
found.append(drive_inv[mid])
# now check the entries either side
return (
linear_search_up(media, mid),
linear_search_down(media, mid
)
# if the filename > media, discard the larger entries
elif drive_inv[mid].split('/')[-1] > media:
if low == mid:
missing.append(media)
return
else:
return binary_search(media, low, mid-1)
# if the filename < media, discard the smaller entries
else:
return binary_search(media, mid+1, high)
if len(drive_inv) == 0:
return
else:
return binary_search(media, 0, len(drive_inv)-1)
它似乎工作得很好,但它有点难看,将结果附加到全局列表中。我希望它返回所有匹配项的元组。但是,如果我改变:
found.append(drive_inv[line+1])
return linear_search_up(media, line+1)
到:
return (
drive_inv[line+1],
linear_search_up(media, line+1)
)
我最终得到一个如下所示的元组:
(('A001C002', ('A001C002', None)), ('A001C002', ('A001C002', ('A001C002', ('A001C002', None)))))
...这不太好。
这可以重写并且仍然使用递归吗?还是我应该考虑另一种方法?
【问题讨论】:
-
请出示您的实际结果。您在上面写的
return声明永远不会产生您发布的结果。 -
我想你的意思是在排序列表中找到一个字符串,因为所有列表都是有序的。
-
干杯,我已经解决了两个 cmets。
-
当我在此数据上运行您的代码时,
drive_inv = ['A001C000', 'A001C000', 'A001C001', 'A001C002', 'A001C002', 'A001C002', 'A001C003', 'A001C003', 'A001C003', 'A001C004', 'A001C005']并调用了find_media('A001C002', drive_inv),它返回了(None, None),将全局found设置为['A001C002', 'A001C002', 'A001C002'],将全局missing设置为@ 987654332@。您说效果很好,您希望返回的元组值究竟是什么? -
我希望元组返回
('A001C002', 'A001C002', 'A001C002'),而不是使用全局列表。最初,该算法是一个类方法,所以附加到 self.found 很好 - 但我宁愿它是一个全局函数并与其他类共享它。我觉得它不属于某个特定的类,所以我不想使用组合/继承。
标签: python search binary-search