python查找算法有哪几种_实现基本有效的“搜索”算法:Python

模拟搜索算法

这是我的问题:

在给定的文档(字符串)中,例如:

"hello there my name is dominic and my name is very special"

和searchTerm(列表),例如:

['my','dominic'] or ['dominic','my'] (shouldn't matter)

算法将返回包含以下内容的文档的最短摘录:

>>> 'dominic and my'

因为

>>> 'my name is dominic'

比以前包含更多的单词。

这是我目前的想法:

通过创建一个内部列表元素数量等于搜索词数量的列表来开始算法。在每个列表的内部将是索引,该搜索元素将出现在文档中。

document = document.split();

所以searchTerms = ['my', 'dominic']会回来

[[2,7], [5]]

因为my出现在索引处2,7并且dominic仅出现在5。

然后,算法将获取此列表并生成所有可能性的列表:

[[2,5], [7,5]]

如您所见,文档字符串中有两个子字符串,其中包含my和dominic。然后,算法可以采用我做的两个内部列表的范围。max()-min()这将告诉我文档的第二个摘录小于第一个摘录,然后return document[5:(7+1)]可能是预期的结果。

就我的想法而言,这就是我到目前为止所拥有的:

document = "hello there my name is dominic and my name is very special"

searchTerms = ['my', 'dominic']

def answer(document, searchTerms):

index = []

document = document.split()

for a in range(0, len(searchTerms)):

index.append([i for i, x in enumerate(document) if x == searchTerms[a]])

return index

到目前为止,这[[2,7],[5]]仍然是我遇到的一个主要问题:

-效率:

此解决方案对于极大的文档字符串和搜索词列表是否有效?如果不能,那么可以做些什么来提高效率,或者我的初衷不是很好

感谢您对解决此问题的任何见解,谢谢。

解决方案

您的算法在平庸的输入上的执行速度可能会非常慢。假设您有10个搜索词和包含10000个单词的文本。在这种情况下,可能每个术语都有1000个索引的列表。最终将产生1000 ^ 10的总可能性。

就大O表示法而言,复杂度为O((n / k)^ k),其中n是文本中的术语数,k-搜索项的数量。

这是想法更快的算法。在逐个单词地迭代文档时,我们需要跟踪最接近当前位置的搜索词索引。我们称其为结构查询(简单的python字典)。快速示例:

"hello there my name is dominic and >my< name is very special"

假设我们要访问突出显示的“我的”单词。此时,查询为{“ my”:2,“ dominic”:5}。当前的“我的”将更接近文本中的任何其他单词。因此,当访问下一个单词(“名称”)时,我们将更新版本{{my“:7,” dominic“:5}。显而易见,最佳解决方案与查找状态之一相对应。因此,要获得答案,只需跟踪字典中的max()-min()值即可。注意:只有当所有搜索词都作为查找关键字出现时,您才应该开始跟踪。

在每次出现搜索词时,我们都需要从位置查找中迭代k个值,因此该算法的复杂度为O(nk)。

为了使它更好,您还可以将平衡BST与来自查找的索引一起使用。现在,除了可以迭代查找值(O(k))之外,您还可以在O(logk)中检索最小索引:

min_index = bst.min()

old_index=lookup[curr_term] # O(1)

bst.delete(old_index) # O(logk)

bst.insert(new_index) # O(logk)

在这种情况下,总复杂度将为O(nlogk)。

编辑。没有树优化的代码(在Python中找不到内置的BST):

document = "hello there my name is dominic and my name is very special"

searchTerms = { 'my', 'dominic' } # set has faster lookups

doc_words = document.split()

from sys import maxint

def search(words, terms):

found_terms = [[i,x] for i,x in enumerate(words) if x in terms]

lookup = {}

cnt = maxint

k = len(terms)

start,end=-1,-1

for i,w in found_terms:

lookup[w] = i

if k == len(lookup):

min_idx = min(lookup.values())

curr = i - min_idx

if curr < cnt:

cnt,start,end = curr,min_idx,i

return words[start:end + 1]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值