Python 拼字游戏:假设你正在尝试完成一个纵横字谜
在纵横填字游戏中,我们会给出一些字母,我们必须找出我们能从中拼出的完整单词。 例如,给定相同顺序的字母“cwd”,我们可以用它来生成单词“crossword”或“crowd”。但是如果“dw”是按这个顺序给出的,我们就不能用它来做“纵横字谜”,因为d和w在这里的顺序相反 我们必须找到一种有效的方法,并为此过程编写代码。 代码将采用两行中的两个字符串作为输入。第一个字符串将包含纵横字谜(“cwd”)上的字母,第二个字符串将包含我们要检查的单词(即,我们要检查单词是否可以由相同顺序的给定字母组成)。 如果单词可以形成,则输出应为“是”,否则应为“否” 我编写了一个代码:Python 拼字游戏:假设你正在尝试完成一个纵横字谜,python,regex,Python,Regex,在纵横填字游戏中,我们会给出一些字母,我们必须找出我们能从中拼出的完整单词。 例如,给定相同顺序的字母“cwd”,我们可以用它来生成单词“crossword”或“crowd”。但是如果“dw”是按这个顺序给出的,我们就不能用它来做“纵横字谜”,因为d和w在这里的顺序相反 我们必须找到一种有效的方法,并为此过程编写代码。 代码将采用两行中的两个字符串作为输入。第一个字符串将包含纵横字谜(“cwd”)上的字母,第二个字符串将包含我们要检查的单词(即,我们要检查单词是否可以由相同顺序的给定字母组成)。
x = re.search(letters, guess)
if (x):
print("yes")
else:
print("no")
但是我没有得到正确的输出
在哪里,
字母=ccwd#纵横字谜中已有字母
guess=crossword#word to check for fit在第一个示例中,您希望找到一个包含
c
、后跟任意(或无)、后跟w
、后跟任意(或无)、后跟d
的单词
“任意(或无)”的正则表达式是*
因此,您需要查找以下正则表达式:
c.*w.*d
如果您正在寻找一个通用的解决方案,请尝试此方法-假设您有一个字典单词列表,我们称之为
lst
,并且您得到了一个模式,比如pat
,并且您希望找出列表中的哪些单词与该模式匹配。这可以通过构造正则表达式来实现,同时通过*
分隔每个模式字符,以允许在它们之间插入0
或更多字符。下面的程序实现了这一点-
pattern = "xyz" # can be replaced to have the desired pattern
lst =["crossword", "crowd"] # this can be replaced to contain the words of your choice
pattern = '.*'.join(list(pattern)) # modifies the pattern to include .* between each of the characters of the pattern
obj = re.compile(pattern) # create compiled regex object to use it again and again
for word in lst:
if obj.search(word):
print "Yes"
else:
print "No"
如前所述,在输入中添加特殊字符b/w字母并查找该模式
此代码适用于您的问题
### import Library for using re.compile() method
import re
### letters already in the crossword
letters=input()
### word to check for fit
guess=input()
### modify letters to include .* between each character
x=re.findall(".*".join(list(letters)),guess)
if (x):
print("yes")
else:
print("no")
对于定义的问题,可以使用正则表达式,但应涵盖添加前缀或后缀的情况(而不仅仅是两者之间的字母): 如果不允许使用库,可以使用递归函数:
def match(letters,guess):
if not letters: return True # stop recursion
if not guess: return False # exhausted guess but not letters
s = int(letters[0]==guess[0]) # next letter? (s=1)
return match(letters[s:],guess[1:]) # recurse for rest
match("cwd","crossword") --> True
match("cwd","crowd") --> True
match("cwd","crowded") --> True
match("cwd","overcrowded") --> True
match("cwd","wicked") --> False
对于真正的纵横字谜,一个非常有效的方法是为每个长度位置字母建立单词集索引。然后,您可以组合不完整单词的已知字母位置的集合:
例如:
with open("/usr/share/dict/words") as wf:
words = [w.lower() for w in wf.read().split("\n") if len(w)>=2]
cIndex = dict() # { (length,position,letter): set of words }
for word in words:
for i,c in enumerate(word):
cIndex.setdefault((len(word),i,c),set()).add(word)
def findwords(placed):
result = None
s = len(placed)
for i,c in enumerate(placed): #Run through known letters/positions
if c=="." : continue
if result is None:
result = cIndex.get((s,i,c),set()).copy()
else:
result &= cIndex.get((s,i,c),set()) # combine word sets
return result or set()
加载索引可能需要几秒钟,但在那之后,响应时间是瞬时的
输出:
print(findwords(".l.p..n."))
# {'slapping', 'aleppine', 'clipping', 'slipband', 'oliphant', 'elephant', 'clupeine', 'slipping', 'flippant', 'elaphine', 'clepsine', 'clapping', 'flopwing', 'slopping'}
您还可以使用该功能解决拼字问题,方法是输入不同长度的字母并过滤可用字母:
from collections import Counter
def fitWord(placed,letters,maxLen=None):
if maxLen is None:
maxLen = len(placed)-placed.count(".")+len(letters)
result = findwords(placed)
if len(placed)<maxLen:
result |= fitWord("."+placed,letters,maxLen)
result |= fitWord(placed+".",letters,maxLen)
letterCounts = Counter(letters)+Counter(placed.replace(".",""))
return {w for w in result if not Counter(w)-letterCounts}
print(fitWord("l.p..n","eehatoi"))
# {'elaphine', 'elephant', 'lophine', 'lepton', 'oliphant'}
从集合导入计数器
def fitWord(已放置,字母,最大值=无):
如果maxLen为无:
maxLen=len(已放置)-已放置。计数(“.”+len(字母)
结果=FindWord(已放置)
如果len(放置)你必须告诉我们字母
和猜测
是什么。我认为她正在寻找一个通用的解决方案,但这是一个特殊的情况。@yabhishek此代码对通用解决方案的适应性很小。你的反对意见是什么?我的观点是,如果给定了模式,可以通过在其字符之间插入*
s作为pattern='.*.join(list(pattern))
。使用Regex import re let=input()guess=input()scrabble=re.findall(.*)。join(list(let)),guess)if(scrabble):print(“yes”)else:print(“no”)
with open("/usr/share/dict/words") as wf:
words = [w.lower() for w in wf.read().split("\n") if len(w)>=2]
cIndex = dict() # { (length,position,letter): set of words }
for word in words:
for i,c in enumerate(word):
cIndex.setdefault((len(word),i,c),set()).add(word)
def findwords(placed):
result = None
s = len(placed)
for i,c in enumerate(placed): #Run through known letters/positions
if c=="." : continue
if result is None:
result = cIndex.get((s,i,c),set()).copy()
else:
result &= cIndex.get((s,i,c),set()) # combine word sets
return result or set()
print(findwords(".l.p..n."))
# {'slapping', 'aleppine', 'clipping', 'slipband', 'oliphant', 'elephant', 'clupeine', 'slipping', 'flippant', 'elaphine', 'clepsine', 'clapping', 'flopwing', 'slopping'}
from collections import Counter
def fitWord(placed,letters,maxLen=None):
if maxLen is None:
maxLen = len(placed)-placed.count(".")+len(letters)
result = findwords(placed)
if len(placed)<maxLen:
result |= fitWord("."+placed,letters,maxLen)
result |= fitWord(placed+".",letters,maxLen)
letterCounts = Counter(letters)+Counter(placed.replace(".",""))
return {w for w in result if not Counter(w)-letterCounts}
print(fitWord("l.p..n","eehatoi"))
# {'elaphine', 'elephant', 'lophine', 'lepton', 'oliphant'}