You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断数组是否为无重复组合?Ruby数组组合操作示例

判断数组是否为原数组的无重复组合

针对你的需求,我整理了两种不同场景下的判断方案,分别对应Ruby内置Array#combination方法的严格输出,以及数学意义上的无重复组合判断:

场景1:严格匹配Ruby combination方法的结果(考虑元素顺序)

Ruby的combination方法生成的子数组会保持原数组中元素的相对顺序,比如source.combination(2)不会生成[:b, :a]这样的数组。如果需要严格判断目标数组是否是该方法生成的有效组合,可以用以下实现:

source = [:a, :b, :c, :d, :e]

def valid_combination?(target, source)
  # 第一步:检查目标数组所有元素都属于原数组,且自身无重复
  return false unless (target - source).empty? && target.uniq == target
  
  # 第二步:检查目标数组的长度在合法范围内(1到原数组长度)
  k = target.size
  return false if k < 1 || k > source.size
  
  # 第三步:验证目标数组是否存在于combination(k)的结果中
  source.combination(k).include?(target)
end

# 测试示例
puts valid_combination?([:a], source)                # => true
puts valid_combination?([:a, :b], source)            # => true
puts valid_combination?([:b, :a], source)            # => false(不符合原数组元素顺序)
puts valid_combination?([:a, :f], source)            # => false(包含原数组外元素)
puts valid_combination?([:a, :a], source)            # => false(存在重复元素)
puts valid_combination?([:a, :b, :c, :d, :e], source) # => true

优化版本(适合大数组)

如果原数组元素较多,生成所有组合会影响效率,我们可以通过验证元素在原数组中的索引是否严格递增来实现,无需生成全部组合:

source = [:a, :b, :c, :d, :e]
# 预先存储原数组元素的索引,提升查询效率
element_indices = source.each_with_index.to_h

def valid_combination_optimized?(target, element_indices)
  # 检查所有元素都存在于原数组,且自身无重复
  return false unless target.all? { |elem| element_indices.key?(elem) } && target.uniq.size == target.size
  
  # 检查元素在原数组中的索引严格递增(保证相对顺序符合combination的规则)
  prev_index = -1
  target.each do |elem|
    current_index = element_indices[elem]
    return false if current_index <= prev_index
    prev_index = current_index
  end
  
  # 检查长度合法
  target.size.between?(1, element_indices.size)
end

# 测试示例
puts valid_combination_optimized?([:a, :c], element_indices) # => true
puts valid_combination_optimized?([:c, :a], element_indices) # => false
puts valid_combination_optimized?([:b, :d, :e], element_indices) # => true

场景2:数学意义上的无重复组合(不考虑元素顺序)

如果只需要判断目标数组是原数组的一个无重复子集(即数学概念中的组合,不关心元素顺序),可以通过集合来实现:

source = [:a, :b, :c, :d, :e]
source_set = source.to_set

def valid_combination_math?(target, source_set)
  target_set = target.to_set
  # 三个条件:目标数组无重复、目标是原数组的子集、长度在合法范围
  target.size == target_set.size && source_set.superset?(target_set) && target.size.between?(1, source_set.size)
end

# 测试示例
puts valid_combination_math?([:b, :a], source_set) # => true(数学上属于有效组合)
puts valid_combination_math?([:a, :b], source_set) # => true
puts valid_combination_math?([:a, :a], source_set) # => false(存在重复)
puts valid_combination_math?([:f], source_set)     # => false(元素不在原数组中)

内容的提问来源于stack exchange,提问作者anquegi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:40:07