单词游戏中高效实现禁止输入被其他单词完全包含的单词的方法
单词游戏中高效实现禁止输入被其他单词完全包含的单词的方法
看起来你遇到的核心问题是混淆了「字母集合包含」和「连续子串包含」——你之前用集合的issubset方法会忽略字母顺序,自然会把像pitch和chip这种字母异位词误判成互相包含,这显然不是你想要的效果。
你的需求是禁止输入被已存在单词作为连续子串完全包含的单词(比如set在subset里),或者反过来禁止输入包含已存在单词的单词?不管是哪种情况,我们都需要检查字符串的连续子串关系,而不是字母集合的关系。
基础高效方案(适合单词数量不多的情况)
Python内置的字符串in运算符已经做了高度优化(底层用了类似Boyer-Moore的高效匹配算法),比你自己写的嵌套循环滑动窗口快得多,直接用它就足够解决问题。我们还可以先通过长度过滤减少不必要的检查:
noWord = False current_word = word.lower() # 统一转小写,避免大小写问题,可根据需求调整 current_len = len(current_word) for used_word in used_words: used_len = len(used_word) used_word_lower = used_word.lower() if current_len == used_len: # 长度相同,只有完全重复才禁止 if current_word == used_word_lower: noWord = True break elif current_len < used_len: # 当前单词更短,检查是否是已用单词的连续子串 if current_word in used_word_lower: noWord = True break else: # 当前单词更长,检查是否包含已用单词作为连续子串 if used_word_lower in current_word: noWord = True break if not noWord: # 计算单词得分 calculate_score(current_word) # 记得把当前单词加入已用单词列表 used_words.append(word)
这个方案的好处是代码简洁,对于普通规模的单词游戏(比如几百上千个单词)完全够用,效率也很高。
进阶优化方案(适合单词数量极多的情况)
如果你的游戏会有大量已用单词(比如上万级),可以把单词按长度分组存储,这样检查的时候只需要遍历相关长度的单词,进一步减少不必要的遍历:
from collections import defaultdict # 初始化按长度分组的字典,用来维护已用单词 word_groups = defaultdict(list) def add_used_word(new_word): """把新单词加入分组字典""" word_lower = new_word.lower() word_groups[len(word_lower)].append(word_lower) # 检查当前输入单词是否符合要求 current_word = word.lower() current_len = len(current_word) noWord = False # 第一步:检查同长度的单词是否重复 for existing_word in word_groups.get(current_len, []): if existing_word == current_word: noWord = True break if not noWord: # 第二步:检查更长的单词是否包含当前单词 for length in word_groups: if length > current_len: for existing_word in word_groups[length]: if current_word in existing_word: noWord = True break if noWord: break if not noWord: # 第三步:检查更短的单词是否被当前单词包含 for length in word_groups: if length < current_len: for existing_word in word_groups[length]: if existing_word in current_word: noWord = True break if noWord: break if not noWord: # 计算得分并加入已用单词 calculate_score(current_word) add_used_word(word)
为什么你的滑动窗口方法效率低?
你自己实现的嵌套循环滑动窗口,本质是手动遍历所有可能的子串进行匹配,这种方法的时间复杂度是O(n*m)(n是已用单词长度,m是当前单词长度),而Python内置的in运算符用的是更高效的字符串匹配算法,时间复杂度更低(平均情况接近O(n)),所以自然会快很多。
备注:内容来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

