Python 如何在长随机字符串中查找可能的英语单词?

Python 如何在长随机字符串中查找可能的英语单词?,python,dictionary,information-retrieval,trie,Python,Dictionary,Information Retrieval,Trie,我正在做一个艺术项目,我想看看是否有任何信息从一长串字符(~28000)中浮现出来。这有点像解决一堆乱七八糟的问题。下面是一个片段: JFIFDCCEAQBRCBDRSTCAQBRCRISAXOVSUYUIATHWDJXBINWAJFGVLXVDPDCKSZKCYRLLIQXSDPVmJJQRCZRRMAAIPUZEKPYQLMYMEDVOVSUDCECCGWNDLGWAQREGGPQQFGOESRIDFGLDBWFMRSMPMVHTMGHRGRJFLFCDLLxDJZERKZBWYYKYKYK

我正在做一个艺术项目,我想看看是否有任何信息从一长串字符(~28000)中浮现出来。这有点像解决一堆乱七八糟的问题。下面是一个片段:

JFIFDCCEAQBRCBDRSTCAQBRCRISAXOVSUYUIATHWDJXBINWAJFGVLXVDPDCKSZKCYRLLIQXSDPVmJJQRCZRRMAAIPUZEKPYQLMYMEDVOVSUDCECCGWNDLGWAQREGGPQQFGOESRIDFGLDBWFMRSMPMVHTMGHRGRJFLFCDLLxDJZERKZBWYYKYKYKYKYKYKYKYKYKKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYKYCezoumpevMuwxeufdrrWhsmFirKwxFadCefLmcMucqerchkCwVvCwCwCwVxOwnifaqyawevauxNvFbSkijBtyLwJvZrNuxAirpunKavVbHfBfBfBfBfBfBfBfBfBfBfBfRbRxBfRxBfRbNxGjGjMqIPrSmRxAcqHqHgHgWwWwWxHwWwWxHbWxCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCqHqH

搜索此字符串中所有可能嵌入的英语单词(向前和向后)的最有效方法是什么


什么是检查子字符串的有用字典?有好的图书馆可以做这种事吗?我四处搜索,找到了一些有趣的TRIE解决方案;但是他们中的大多数人都是在处理这样一种情况,即你事先就知道一组单词

这里是一个应该很有用的对分/二进制搜索

def isaprefix(frag, wordlist, first, last):
    """
    Recursive binary search of wordlist for words that start with frag.

    assumes wordlist is a sorted list
    typically called with first = 0 and last = len(wordlist)

    first,last -->> integer
    returns bool
    """

    # base case - down to two elements
    if (last - first) < 2:
        # return False unless frag is a prefix
        # of either of the two remaining words
        return wordlist[first].startswith(frag) or wordlist[last].startswith(frag)

    #mid = (first + last)/2
    midword = wordlist[(first + last) / 2]

    # go ahead and return if you find one
    # a second base case?
    if midword.startswith(frag):
        return True

    #print word, ' - ', wordlist[mid], ' - ', wordlist[mid][:len(word)], ' - ', isprefix
    # start the tests
    # python does just fine comparing strings
    if frag < midword:
        # set the limits to the lower half
        # of the previous range searched and recurse
        return isaprefix(frag, wordlist, first, mid-1)

    # frag is > midword: set the limits to the upper half
    # of the previous range searched and recurse
    return isaprefix(frag, wordlist, mid+1, last)
def-isaffix(frag,单词列表,第一个,最后一个):
"""
对以frag开头的单词列表进行递归二进制搜索。
假设wordlist是一个排序列表
通常使用first=0和last=len(单词列表)调用
第一,最后-->>整数
返回布尔
"""
#基本情况-减少到两个元素
如果(最后一个-第一个)<2:
#返回False,除非frag是前缀
#剩下的两个词中的任何一个
返回单词列表[first].StartWith(frag)或单词列表[last].StartWith(frag)
#中间=(第一个+最后一个)/2
middord=wordlist[(第一个+最后一个)/2]
#如果你找到了,请继续返回
#第二个基本情况?
如果midword.startswith(frag):
返回真值
#打印单词“-”,单词表[mid],“-”,单词表[mid][:len(word)],“-”,isprefix
#开始测试
#python在比较字符串方面做得很好
如果fragmidword:设置上半部分的限制
#搜索并递归上一个范围的
返回ISAPRIX(frag,单词列表,mid+1,最后一个)

我使用这个解决方案,在10万个单词的字典中,从28000个随机字符的语料库中,在0.5秒内前后查找所有单词。它在O(n)时间内运行。它需要一个名为“words.txt”的文件,这是一个字典,单词之间用某种空格分隔。我在
/usr/share/dict/words
中使用了默认的unix单词列表,但我相信如果不是这样的话,您可以在网上找到很多文本文件词典

from random import choice
import string

dictionary = set(open('words.txt','r').read().lower().split())
max_len = max(map(len, dictionary)) #longest word in the set of words

text = ''.join([choice(string.ascii_lowercase) for i in xrange(28000)])
text += '-'+text[::-1] #append the reverse of the text to itself

words_found = set() #set of words found, starts empty
for i in xrange(len(text)): #for each possible starting position in the corpus
    chunk = text[i:i+max_len+1] #chunk that is the size of the longest word
    for j in xrange(1,len(chunk)+1): #loop to check each possible subchunk
        word = chunk[:j] #subchunk
        if word in dictionary: #constant time hash lookup if it's in dictionary
            words_found.add(word) #add to set of words

print words_found

您可以考虑从整个词典中创建一个序列,然后使用smith water man或任何启发式局部对齐算法对齐它们以获得序列中的单词:它们是您选择的词典中的一组单词。请从第一个字符开始。这是一个词吗?添加下一个字符。这是一个词吗?有没有以这些字符开头的单词?否-从大字符串中删除第一个字符并重新开始。是的,这是一个词吗?有没有以这些字符开头的单词?否-从大字符串中删除第一个字符并重新开始。是的,这是一个词吗。。。。。。。。。。。或者也许是一个更好的主意-是字符串中的第一个字典单词吗?字符串中的第二个单词是字典中的吗?字符串中的第三个字典单词是。。。第n个字典单词在字符串中吗?您可以使用二进制/二等分搜索在单词列表中进行搜索,以查看一组字母是单词还是前缀。(1)将字典插入
trie
(2)迭代你的数据,看看你是否能将一个trie条目与当前的起始位置相匹配。一个很小的问题:
text+=text[:-1]
可能会带来一个问题,因为有可能
“red”
只存在于
text
的末尾,在添加反面后,中间有
“redder”
,这不是原始字符串中的一个词。我知道这一点,但认为这没有什么大不了的。我早该知道,所以我会叫我出来;)我编辑它是为了解决这个问题。很明显,你在范围内有I,在范围内有j。。。。这怎么可能在O(n)时间内运行呢?
j
max\u len
为界,这是一个常数(
max\u len
是字典中最长单词的长度)。我想我已经部分地实现了这一点。我正在使用测试字符串'abzcatrwxadfsa',并获得>>>打印(words_-find){'sava',saya',saka',alab',sara',ahab',saha',safa',sana',sala',sapa',arab',saga',sada',sava',anab',sama',akab',zcat',结果中甚至没有字母。出了什么问题?