减少本程序的时间复杂性

时间:2015-08-31 05:15:03

标签: python algorithm time-complexity testcase code-complexity

问题 - 编写一个名为answer(document,searchTerms)的函数,它返回文档的最短片段,其中包含所有给定的搜索词。搜索字词可以按任何顺序出现。

Inputs:
(string) document = "many google employees can program"
(string list) searchTerms = ["google", "program"]
Output:
(string) "google employees can program"

 Inputs:
(string) document = "a b c d a"
(string list) searchTerms = ["a", "c", "d"]
 Output:
(string) "c d a"

我的程序正在给出正确答案,但由于我在做笛卡尔积,因此时间复杂度非常高。如果输入非常高,那么我无法清除那些测试用例。我无法降低此程序的复杂性,任何帮助将不胜感激。感谢

import itertools

import sys

def answer(document, searchTerms):

    min = sys.maxint

    matchedString = ""

    stringList = document.split(" ")

    d = dict()

    for j in range(len(searchTerms)):

        for i in range(len(stringList)):

            if searchTerms[j] == stringList[i]:

                d.setdefault(searchTerms[j], []).append(i)

    for element in itertools.product(*d.values()):

        sortedList = sorted(list(element))

        differenceList = [t - s for s, t in zip(sortedList, sortedList[1:])]

       if min > sum(differenceList):

          min = sum(differenceList)
          sortedElement = sortedList

          if sum(differenceList) == len(sortedElement) - 1:
            break

    try:
        for i in range(sortedElement[0], sortedElement[len(sortedElement)-1]+1):

            matchedString += "".join(stringList[i]) + " "

    except:
        pass

    return matchedString

如果有人想要克隆我的程序,请code

2 个答案:

答案 0 :(得分:1)

一种解决方案是使用两个索引(startstop)迭代文档。您只需跟踪searchTermsstart之间stop中每个stop的数量。如果不是全部存在,则增加start直到它们(或者您到达文档的末尾)。如果全部存在,则会增加searchTerms,直到所有searchTerms不再存在为止。每当所有O(N)出现时,您都要检查该候选人是否比以前的候选人更好。这应该可以在O(1)时间内完成(使用有限数量的搜索字词或将搜索字词放入具有start = 0 stop = 0 counts = dict() cand_start = None cand_end = None while stop < len(document): if len(counts) < len(searchTerms): term = document[stop] if term in searchTerms: if term not in counts: counts[term] = 1 else: counts[term] += 1 else: if cand_start is None or stop-start < cand_stop-cand_start: cand_start = start cand_stop = stop term = document[start] if term in counts: if counts[start] == 1: del counts[start] else: counts[start] -= 1 start += 1 查找的集合中)。类似的东西:

➜  logs  ls -l | wc -l
11135951
➜  logs  rm log*
-bash: fork: Cannot allocate memory

答案 1 :(得分:1)

Aho-Corasick algorithm将在线性时间内搜索文档以查找多个搜索字词。它的工作原理是从搜索术语构建有限状态自动机,然后通过该自动机运行文档。

建立FSA并开始搜索。找到搜索词后,将它们存储在元组数组中(搜索词,位置)。找到所有搜索字词后,请停止搜索。列表中的最后一项将包含找到的最后一个搜索词。这将为您提供范围的结束位置。然后在找到的术语列表中向后搜索,直到找到所有术语。

所以,如果你正在寻找[&#34; cat&#34;,&#34; dog&#34;,&#34; boy&#34;,&#34; girl&#34;],你可能得到类似的东西:

cat - 15
boy - 27
cat - 50
girl - 97
boy - 202
dog - 223

所以你知道范围的结尾是226,向后搜索你找到所有四个术语,最后一个是&#34; cat&#34;在第50位。