我有10个任意字母,需要检查单词文件
的最大长度匹配我刚刚开始学习RE,似乎找不到合适的模式
我最近盯着学习Python,但在RE之前,可能还不需要RE,这可以在没有它的情况下解决
我想解决方案甚至对于新手程序员/脚本编写者来说都是已知的,但对我来说却不知道 感谢
答案 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}然后对于文本文件中的每个单词,查看是否可以在任意字母的词典中找到该单词的所有字母。如果是这样,那么这就是你的候选词之一。
所以: 我们 壁 井
井中的所有字母都可以在你的任意字母词中找到,所以保存它和它的长度以便与其他字词进行比较。