从任意字母中查找最大长度字

时间:2010-08-04 04:31:08

标签: python puzzle iterator

我有10个任意字母,需要检查单词文件

的最大长度匹配
  1. 我刚刚开始学习RE,似乎找不到合适的模式

    • 第一个想法是使用set:[10 chars]但它也重复包含的字符,我不知道如何避免这种情况
  2. 我最近盯着学习Python,但在RE之前,可能还不需要RE,这可以在没有它的情况下解决

    • 使用“for this in this:”迭代器似乎不合适,但也许itertools可以轻松完成(我不熟悉)
  3. 我想解决方案甚至对于新手程序员/脚本编写者来说都是已知的,但对我来说却不知道 感谢

3 个答案:

答案 0 :(得分:2)

我猜这就像在给定一组拼字游戏拼贴的情况下找到可能的单词一样,这样一个角色只能重复在原始列表中重复的次数。

诀窍是根据包含源字母的集合有效地测试word文件中每个单词的每个字符。对于每个字符,如果在测试集中找到,则将其从测试集中删除并继续;否则,这个单词不匹配,继续下一个单词。

Python有一个很好的函数all,用于根据序列中的元素测试一组条件。 all具有“短路”的附加功能,即一旦一个项目失败,就不再进行测试。因此,如果你的候选词的第一个字母是'z',并且你的源字母中没有'z',那么在候选词中测试任何更多的字母是没有意义的。

我写这篇文章的第一步就是:

matches = []
for word in wordlist:
    testset = set(letters)
    if all(c in testset for c in word):
        matches.append(word)

不幸的是,这里的错误是如果源字母包含单个'm',则具有几个'm'的单词将错误地匹配,因为每个'm'将分别匹配源测试集中给定的'm'。所以我需要删除匹配的每个字母。

我利用set.remove(item)返回None的事实,Python将其视为布尔False,并扩展了我在调用all时使用的生成器表达式。对于每个c in word,如果在testset中找到它,我想另外从testset中删除它,类似于(伪代码,不是有效的Python):

all(c in testset and "remove c from testset" for c in word)

由于set.remove返回None,我可以用“not testset.remove(c)”替换上面引用的位,现在我有一个有效的Python表达式:

all(c in testset and not testset.remove(c) for c in word)

现在我们只需将它包装在一个循环中,检查列表中的每个单词(确保在检查每个单词之前构建一个新的testset,因为我们的all测试现在已成为一个破坏性测试):< / p>

for word in wordlist:
    testset = set(letters)
    if all(c in testset and not testset.remove(c) for c in word):
        matches.append(word)

最后一步是按降序长度对匹配进行排序。我们可以传递一个关键功能来排序。内置len会很好,但会按升序排序。要将其更改为降序排序,我们使用lambda不是len,而是-1 * len

matches.sort(key=lambda wd: -len(wd))

现在你可以打印出最长的单词,在匹配[0],或迭代所有匹配并打印出来。

(我很惊讶这种蛮力方法运行良好。我使用了2of12inf.txt单词列表,包含超过80,000个单词,并且对于10个字符的列表,我在大约0.8秒内返回匹配列表我的小型1.99GHz笔记本电脑。)

答案 1 :(得分:0)

我认为此代码可以满足您的需求:

>>> words = open('file.txt')
>>> max(len(word) for word in set(words.split()))

如果您需要更复杂的标记,例如,如果您不使用拉丁文本,则应使用NLTK

>>> import nltk
>>> words = open('file.txt')
>>> max(len(word) for word in set(nltk.word_tokenize(words)))

答案 2 :(得分:0)

我假设您正在尝试找出10个任意字母中最长的单词。

你可以在字典中保留10个任意字母及其出现的频率。

例如,你的4(简单地用4而不是10)任意字母是:e,w,l,l。这将是一个字典: {'e':1,'w':1,'l':2}

然后对于文本文件中的每个单词,查看是否可以在任意字母的词典中找到该单词的所有字母。如果是这样,那么这就是你的候选词之一。

所以: 我们 壁 井

井中的所有字母都可以在你的任意字母词中找到,所以保存它和它的长度以便与其他字词进行比较。