【问题标题】:search text using binary search in python在 python 中使用二进制搜索搜索文本
【发布时间】:2019-06-26 20:41:48
【问题描述】:

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

我的列表中有超过一千个文件,因此我想使用二进制搜索。

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

【问题讨论】:

  • 你的问题是什么?
  • 如果你运行我上面粘贴的代码,它不会给出预期的结果。在我的情况下,结果应该是 2,因为“橙色”首先出现在“pi.txt”中。谢谢。

标签: python binary-search


【解决方案1】:

我认为如果条件有点太多,你可以设法得到这样的预期结果:

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

【讨论】:

  • 您的解决方案按预期工作。感谢您的帮助!
【解决方案2】:

您的二分搜索并不是真正在寻找相等性,因此可以稍微简化一下:

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&gt;=lo),此时 lo 将位于第一个匹配项的索引上,如果有则位于 len(files)没有匹配项。

【讨论】:

  • 您的解决方案按预期工作。感谢您的帮助!
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2021-04-20
    • 2016-02-28
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    相关资源
    最近更新 更多