Python 如何将所有可能的单词从字符串中排序?
我想知道如何继续这个任务,以这个字符串为例“thingsandstuff” 如何从这个字符串中生成所有可能的字符串,以便在英语词典中单独查找它们 目标是在不包含空格的字符串中查找有效的英语单词Python 如何将所有可能的单词从字符串中排序?,python,Python,我想知道如何继续这个任务,以这个字符串为例“thingsandstuff” 如何从这个字符串中生成所有可能的字符串,以便在英语词典中单独查找它们 目标是在不包含空格的字符串中查找有效的英语单词 多亏了蛮力方法,即检查每个子字符串,即使对于中等长度的字符串(长度N的字符串具有O(N**2)子字符串),在计算上也是不可行的。除非对您关心的字符串长度有一个非常严格的限制,否则这不会很好地扩展 为了使事情变得更可行,需要更多的知识——您是否对重叠的单词(例如示例中的“things”和“sand”)和/或
多亏了蛮力方法,即检查每个子字符串,即使对于中等长度的字符串(长度
N
的字符串具有O(N**2)
子字符串),在计算上也是不可行的。除非对您关心的字符串长度有一个非常严格的限制,否则这不会很好地扩展
为了使事情变得更可行,需要更多的知识——您是否对重叠的单词(例如示例中的“things”和“sand”)和/或会留下未解释字符的单词感兴趣(例如示例中的“thing”和“and”,让中间词“搁浅”),还是希望将字符串严格划分为并列的(不重叠)没有残留的单词
后者将是最简单的问题,因为自由度急剧下降——本质上是试图确定一系列“断点”,每个断点位于两个相邻字符之间,将字符串拆分为单词。如果是这样的话,您是否需要所有可能的有效拆分(即,您是否需要两个“thing sand”和“事物和”),或者任何一个有效的拆分都可以,或者您的拆分必须优化哪些标准
如果您澄清了所有这些问题,可能会给您更多帮助!蛮力方法,即检查每个子字符串,即使对于中等长度的字符串(长度
N
的字符串具有O(N**2)
子字符串),在计算上也是不可行的.除非对你关心的字符串长度有一个非常严格的限制,否则这不会很好地扩展
为了使事情变得更可行,需要更多的知识——您是否对重叠的单词(例如示例中的“things”和“sand”)和/或会留下未解释字符的单词感兴趣(例如示例中的“thing”和“and”,让中间词“搁浅”),还是希望将字符串严格划分为并列的(不重叠)没有残留的单词
后者将是最简单的问题,因为自由度急剧下降——本质上是试图确定一系列“断点”,每个断点位于两个相邻字符之间,将字符串拆分为单词。如果是这样的话,您是否需要所有可能的有效拆分(即,您是否需要两个“thing sand”和“事物和”),或者任何一个有效的拆分都可以,或者您的拆分必须优化哪些标准
如果您澄清了所有这些问题,可能会为您提供更多帮助!另一种可能是相反的,不是从字符串中生成子字符串,而是抓住所有候选词并将其与字符串匹配 您可以将单词的索引对作为结果(开始、结束)存储在原始字符串中 这可以在正则表达式中轻松完成,如果性能不够,可以使用str.find(),如果性能不够,还可以使用更复杂的字典索引方案或smarts(关于什么可以匹配,什么不可以匹配,请参阅了解更多信息) 这是我的意思的一个例子
candidate = "thingsandstuffmydarlingpretty"
words = file('/usr/share/dict/words').read()
#This generator calls find twice, it should be rewritten as a normal loop
generate_matches = ((candidate.find(word),word) for word in words.split('\n')
if candidate.find(word) != -1 and word != '')
for match in generate_matches:
print "Found %s at (%d,%d)" % (match[1],match[0],match[0] + len(match[1]))
另一种可能是反过来,不是从字符串生成子字符串,而是抓住所有候选词并将它们与字符串匹配 您可以将单词的索引对作为结果(开始、结束)存储在原始字符串中 这可以在正则表达式中轻松完成,如果性能不够,可以使用str.find(),如果性能不够,还可以使用更复杂的字典索引方案或smarts(关于什么可以匹配,什么不可以匹配,请参阅了解更多信息) 这是我的意思的一个例子
candidate = "thingsandstuffmydarlingpretty"
words = file('/usr/share/dict/words').read()
#This generator calls find twice, it should be rewritten as a normal loop
generate_matches = ((candidate.find(word),word) for word in words.split('\n')
if candidate.find(word) != -1 and word != '')
for match in generate_matches:
print "Found %s at (%d,%d)" % (match[1],match[0],match[0] + len(match[1]))
这是我的想法
- 从原始字符串中查找包含1个字符的所有可能字符串
- 从原始字符串中查找包含2个字符的所有可能字符串
- …与原始字符串长度相同
- 从原始字符串中查找包含1个字符的所有可能字符串
- 从原始字符串中查找包含2个字符的所有可能字符串
- …与原始字符串长度相同
然后,将所有问题相加,并与您的词典进行匹配人们谈论这个问题时,好像问题的顺序是可能的子字符串的数量。这是不正确的。这个问题的正确顺序是: O(最小值(dict中的字数、子串组合数)*比较成本) 因此,另一种解决问题的方法是在Vinko的基础上建立字典索引(例如,对于dict中的每一项工作,确定该单词中的字母、单词的长度等)。这可以显著加快速度。例如,我们知道目标“queen”不能与“zebra”匹配(没有z!)(或包含z、r、b、a…)等的任何单词。此外,将dict中的每个单词存储为排序字符串(“zebra”->“aberz”),并进行“字符串中的字符串”(最长公共子字符串)匹配。“eenuq”与“abarz”(不匹配) (注意:我假设原始单词中字母的顺序无关紧要——这是一个“字母袋”,如果有,则进行相应调整) 如果您一次有很多单词要比较,那么可以使用类似的方法进一步降低比较成本
(同时,我也直言不讳,做出了一些Alex没有的假设,所以如果他们错了,那就闭嘴!)人们谈论这个问题时,好像问题的顺序是可能的子字符串的数量。这是不正确的。这个问题的正确顺序是: O(最小值)(dict中的字数,子字符串com的数目
maxwordlength = max(map(len, english_words))
for i in range(len(word)):
for j in range(i+1, min(maxwordlength+i, len(word))):
if word[i:j] in english_words:
print word[i:j]
def all_substrings(val):
return [val[start:end] for start in range(len(val)) for end in range(start + 1, len(val))]
val = "thingsandstuff"
for result in all_substrings(val):
print result
t
th
thi
thin
thing
tu
tuf
u
uf
f
>>> def match(candidate, word):
def next_char(w):
for ch in sorted(w):
yield ch
g = next_char(word)
for cl in sorted(candidate):
try:
wl = g.next()
except StopIteration:
return False
if wl > cl:
return False
while wl < cl:
try:
wl = g.next()
except StopIteration:
return False
if wl > cl:
return False
return True
>>> word = sorted("supernatural")
>>> dictionary = ["super", "natural", "perturb", "rant", "arrant"]
>>> for candidate in dictionary:
print candidate, match(candidate, word)
super True
natural True
perturb False
rant True
arrant True
d = dict([(sorted(word), word) for word in dictionary])
result = [d[k] for k in d.keys() if match(k, word)]