在python中使用二进制搜索搜索文本

在python中使用二进制搜索搜索文本,python,binary-search,Python,Binary Search,我在一个名为data的列表中有几个文件名。我想读取文件的内容,并检查文件中是否出现给定的文本(示例-橙色)。我的文件名按顺序添加到列表中,即如果给定的文本“orange”出现在文件pi.txt(索引2)中,它也将出现在索引2之后的所有文件中,当然,我希望获得文本“orange”最先出现的索引或文件名 我在一个列表中有上千个文件,因此我想使用二进制搜索 data = ['ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt'] targe

我在一个名为data的列表中有几个文件名。我想读取文件的内容,并检查文件中是否出现给定的文本(示例-橙色)。我的文件名按顺序添加到列表中,即如果给定的文本“orange”出现在文件pi.txt(索引2)中,它也将出现在索引2之后的所有文件中,当然,我希望获得文本“orange”最先出现的索引或文件名

我在一个列表中有上千个文件,因此我想使用二进制搜索

data = ['ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt']
target = "orange"

def binary_search(a, x):
    lo = 0
    hi = len(a)

    while lo < hi:
        mid = (lo + hi) // 2

        if not x in open(a[mid]).read():
            lo = mid + 1
        elif x in open(a[mid]).read():
            hi = mid
        elif mid > 0 and x in open(a[mid-1]).read():
            hi = mid
        else:
            return mid

    return -1

print(binary_search(data, target))



$ cat ae.txt
papaya
guava

$ cat ac.txt 
mango
durian
papaya
guava

$ cat pi.txt 
orange
papaya
guava

$ cat ad.txt 
orange
papaya
guava

$ cat mm.txt 
orange
papaya
guava

$ cat ab.txt 
orange
papaya
guava
data=['ae.txt','ac.txt','pi.txt','ad.txt','mm.txt','ab.txt']
target=“橙色”
def二进制搜索(a,x):
lo=0
hi=len(a)
当lo0且x处于打开状态(a[mid-1])。读取()
高=中
其他:
中途返回
返回-1
打印(二进制搜索(数据、目标))
$cat ae.txt
番木瓜
番石榴
$cat ac.txt
芒果
榴莲
番木瓜
番石榴
$cat pi.txt
橙色
番木瓜
番石榴
$cat ad.txt
橙色
番木瓜
番石榴
$cat mm.txt
橙色
番木瓜
番石榴
$cat ab.txt
橙色
番木瓜
番石榴

仅当您的文件已按正在使用的搜索键排序时,文件的二进制搜索才起作用,这意味着文件X[n+1]的数据在字典上不得小于文件X[n]。在这种情况下,您必须手动检查每个文件,直到彻底检查所有文件。。。或者像这样构建一个字典文件:

'ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt'
durian 1
guava 0-5
mango 1
orange 2-5
papaya 0-5
第一行表示包含的文件,并通过定位为它们提供索引(例如,“ae.txt”位于位置0)。其他行表示包含每个单词的文件索引

从这里,您可以读取文件名的第一行,通过行中的二进制搜索来查找您要查找的单词(不过,您可能应该找到一种方法来读取O(1)中的特定行,或者将它们放在单独的字典文件中,例如,如果单个字母太多的话)。然后,确定文件名的索引(其在第一行中的位置)是否在单词的行中表示


编写写入初始文件并相应更新的代码似乎很简单,但如果您愿意,我可以帮助您。

我认为if条件太多了,您可以设法获得如下预期结果:

data = ['ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt']
target = "orange"

def binary_search(a, x):
    lo = 0
    hi = len(a)

    while lo < hi:
        mid = (lo + hi) // 2
        print(mid)
        if not x in open(a[mid]).read():
            lo = mid + 1

        elif x in open(a[mid]).read():
            hi = mid
        if lo == hi:
            return lo

        print("low : {}; high : {}".format(lo,hi))

    return -1
index = binary_search(data, target)
print("The index where we first found the word orange is {}, the file name is {}".format(index,data[index]))

您的二进制搜索并不是真正寻找相等,因此可以简化一点:

def binary_search(files, string):
    lo,hi  = 0,len(files)-1
    while hi>=lo:
        mid     = (hi+lo)//2
        if string in open(files[mid]).read(): 
            hi = mid-1
        else: 
            lo = mid+1
    return lo

由于没有相等检查,
hi
lo
将达到停止条件(
hi>=lo
),此时
lo
将位于第一个匹配的索引上,或者如果没有匹配,则位于
len(文件)

您的问题是什么?如果运行上面粘贴的代码,它不会给出预期的结果。在我的例子中,结果应该是2,因为“orange”首先出现在“pi.txt”中。谢谢。您的解决方案按预期工作。谢谢你的帮助!您的解决方案按预期工作。谢谢你的帮助!
def binary_search(files, string):
    lo,hi  = 0,len(files)-1
    while hi>=lo:
        mid     = (hi+lo)//2
        if string in open(files[mid]).read(): 
            hi = mid-1
        else: 
            lo = mid+1
    return lo