Ruby中筛选1+2元素数组排列组合并去重且总和≤目标值的问题
筛选并去重数组组合解决方案
问题背景
有两个数组:
teams = [1,2,3] drivers = [4,5,6]
需要从teams中取1个元素、drivers中取2个元素生成所有排列组合,再筛选出总和≤10的组合,并去除因排列顺序不同产生的重复项(比如[[1], [4,5]]和[[1], [5,4]]视为同一组合)。
问题分析
你之前的代码报错,核心原因是:
- 数组结构为
[[team_num], [d1, d2]],直接调用reduce(:+)或sum会尝试将整数与数组相加,导致undefined method '<='错误 - 使用
permutation生成drivers的组合会产生顺序不同的重复项,需要基于元素集合去重,而非数组本身
解决方案代码
teams = [1,2,3] drivers = [4,5,6] target = 10 # 生成所有组合(保留原逻辑,用permutation) team_options = teams.permutation(1).to_a driver_options = drivers.permutation(2).to_a all_combinations = team_options.product(driver_options) # 第一步:筛选总和≤target的组合 filtered = all_combinations.select do |team_arr, drivers_arr| # 正确计算总和:team元素 + drivers元素之和 total = team_arr.first + drivers_arr.sum total <= target end # 第二步:去重——基于team元素和排序后的drivers数组判断重复 unique_result = filtered.uniq do |team_arr, drivers_arr| [team_arr.first, drivers_arr.sort] end p unique_result # 输出:[[[1], [4, 5]]]
代码说明
- 筛选逻辑:明确提取team的单个元素(
team_arr.first),加上drivers数组的和,避免嵌套数组直接相加的错误 - 去重逻辑:通过
uniq的块参数,将drivers数组排序后作为判断重复的依据——排序后的[4,5]和[5,4]会被视为同一值,从而去除重复组合
如果想简化生成组合的步骤,也可以用combination代替permutation生成drivers的组合(直接生成无顺序重复的组合),这样可以省去后续去重步骤:
teams = [1,2,3] drivers = [4,5,6] target = 10 # 用combination直接生成无顺序重复的drivers组合 team_options = teams.permutation(1).to_a driver_options = drivers.combination(2).to_a all_combinations = team_options.product(driver_options) # 直接筛选即可,无需去重 result = all_combinations.select do |team_arr, drivers_arr| team_arr.first + drivers_arr.sum <= target end p result # 输出:[[[1], [4, 5]]]
内容的提问来源于stack exchange,提问作者ldthompson
相关产品推荐
相关产品推荐

