Ruby生成指定长度范围可重复字母组合 适配NYT Spelling Bee需求
问题原因
原代码使用的Array#permutation是无重复排列方法,仅能生成和输入字母总数量长度一致、每个字母最多出现一次的序列,无法满足允许字母重复、自定义长度范围的需求。
解决方案
有两种实现思路,推荐用第二种反向匹配逻辑,性能更高:
思路1:按需求生成所有候选组合后匹配词典
使用Ruby内置的Array#repeated_permutation方法,该方法支持指定生成序列的长度,且允许元素重复使用,刚好符合你的需求。
修改后的完整代码如下:
# 配置项 letters = ["m","o","r"] min_length = 4 # 纽约时报Spelling Bee要求最小长度为4 max_length = 10 # 可根据需求调整,英文常用单词很少超过15个字符 # 加载词典转为集合,O(1)匹配速度远高于数组的O(n) require 'set' word_set = Set.new File.open('en_words.txt') do |file| file.each_line do |line| word_set.add(line.strip.downcase) end end valid_words = [] # 遍历所有要求的长度 (min_length..max_length).each do |len| # 生成长度为len、允许字母重复的所有排列组合 letters.repeated_permutation(len) do |perm| candidate = perm.join valid_words << candidate if word_set.include?(candidate) end end # 输出去重后的有效结果 p valid_words.uniq
思路2:反向匹配词典(性能更高,推荐)
当输入字母较多、要求的长度范围较大时,生成所有候选组合的计算量会指数级上升,更高效的方式是直接遍历词典,筛选出符合要求的单词:
# 配置项 letters = ["m","o","r"] min_length = 4 max_length = 10 letter_set = letters.to_set # 加载词典 words = File.readlines('en_words.txt').map(&:strip).map(&:downcase) # 直接过滤符合要求的单词 valid_words = words.filter do |word| # 长度符合要求 + 所有字符都在输入字母范围内 word.length.between?(min_length, max_length) && word.chars.all? { |c| letter_set.include?(c) } end p valid_words
额外适配Spelling Bee规则的优化
纽约时报Spelling Bee额外要求所有有效单词必须包含指定的中心字母,你可以在过滤逻辑里加一行校验,进一步缩小结果范围:
# 假设中心字母是"o" center_letter = "o" # 过滤逻辑新增判断 word.include?(center_letter)
内容的提问来源于stack exchange,提问作者Marc Auciello
相关产品推荐
相关产品推荐

