繁体   English   中英

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

[英]search text using binary search in python

在名为data的列表中,文件名很少。 我想读取文件的内容并检查给定的文本(例如-橙色)是否出现在文件中。 我的文件名是按顺序添加到列表的,即如果给定的文本“橙色”出现在文件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 = "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]))

The index where we first found the word orange is 2, the file name is 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

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

仅当文件已经通过您使用的搜索键排序时,才对文件进行二进制搜索,这意味着文件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)中特定行的方法-或如果它们过多,则将它们放在单独的字典文件中,例如单个字母)。 然后,确定文件名的索引(在第一行中的位置)是否在单词的行中表示。

编写可写入初始文件并相应地对其进行更新的代码似乎很简单,但是如果您愿意,我可以为您提供帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM