【问题标题】:Find all subsets in an array查找数组中的所有子集
【发布时间】:2013-12-01 14:02:15
【问题描述】:

我需要帮助来解决这个 ruby​​ 数组问题。

获取数组的所有子集。唯一的一套。没有任何数量的重复。 num_subset([1,2,3]) ==> 结果应该是 [[], ["1"], ["1", "2"], ["1", "2", "3"], ["1", "3"], ["2"], ["2", "3"], ["3"]]

def num_subset(arr)
    holder =[]
    order_subset = [[]]

    (arr.length).times do |m|  
        arr.map do |n|
            holder += [n]  
            order_subset << holder
        end
    holder =[]  # resets holder
    arr.shift  # takes the first element out
    end
    order_subset
end

我的结果 ==> [[], ["1"], ["1", "2"], ["1", "2", "3"], ["2"], ["2", "3"], ["3"]。我的问题是我缺少一个结果["1", "3"]

需要一些帮助来指引我正确的方向。已经花了几个小时。不要使用#combination 快捷方式。我需要手动解决这个问题。

【问题讨论】:

  • “数组的子集”没有意义。 “集合的子集”或“数组的子数组”是有意义的。换句话说,是否允许[1, 1, 2, 3] 作为参数?如果是,那是否等同于[1, 2, 3]?如果不是,那么预期的结果是什么?
  • @sawa,它只是一个独特的集合。没有重复。

标签: ruby arrays string algorithm numbers


【解决方案1】:

递归解

def subsets(arr)
  (l = arr.pop) ? subsets(arr).map{|s| [s,s+[l]]}.flatten(1) : [[]]
end

或以更具描述性的方式

def subsets(arr)
  return [[]] if arr.empty?
  last = arr.pop
  subsets(arr).map{|set| [set, set + [last]]}.flatten(1)
end

【讨论】:

    【解决方案2】:

    我相信这是寻找组合的最红宝石解决方案

    a = [1,2,3]
    
    p (0..a.length).collect { |i|
      a.combination(i).to_a
    }.flatten(1)
    
    # [[], [1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
    

    【讨论】:

      【解决方案3】:

      我创建了一种方法来查找数组的所有子集。我正在使用二进制数来减少数组的迭代次数。

      def find_subset(input_array)
          no_of_subsets = 2**input_array.length - 1
          all_subsets = []
          expected_length_of_binary_no = input_array.length
          for i in 1..(no_of_subsets) do 
              binary_string = i.to_s(2)
              binary_string = binary_string.rjust(expected_length_of_binary_no, '0')
              binary_array = binary_string.split('')
              subset = []
              binary_array.each_with_index do |bin, index|
                  if bin.to_i == 1
                      subset.push(input_array[index]) 
                  end
              end
              all_subsets.push(subset)
          end
          all_subsets
      end
      

      [1,2,3] 的输出为

      [[3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
      

      【讨论】:

        【解决方案4】:

        我的解决方案。

        这里的基本思想是数组的子集是

        数组的子集少一个元素 - 我们称这些旧子集

        包含那个少一个元素的元素数组添加了每个旧子集

        例如 -

        子集([1, 2, 3]) 是 -

        子集([1, 2]) - old_subsets

        将 3 附加到每个 old_subsets

        def subsets(arr)
          return [[]] if arr.empty?
          old_subsets = subsets(arr.drop(1))
          new_subsets = []
          old_subsets.each do |subset|
            new_subsets << subset + [arr.first]
          end
          old_subsets + new_subsets
        end
        

        【讨论】:

          【解决方案5】:
          a = [1, 2, 3]
          arr = []
          
          for i in 0..(a.length) do
            arr = arr + a.combination(i).to_a
          end
          
          > arr
          # [[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
          

          【讨论】:

          • 我已经知道了。尝试解决问题,而不是使用#combination 捷径。
          • @hken27 你没有在问题中写下这个。你应该有。
          • @Santosh 关闭,但您的错误。 i 应该从 0 开始。
          • @sawa,感谢您指出。我没有注意到 qs 中的[]。它不容易阅读。更正了我的答案
          • 拥有[] 是正常定义。假设否则应该需要特殊的动机。可读性应该无关紧要。很好,你纠正了它。
          【解决方案6】:

          看起来您正在查看数组中某处的起点,然后查看从该起点开始的所有子数组,然后将起点向下移动。这样,您就错过了有间隙的子数组。对于[1,2,3],唯一有间隙的子数组是[1,3]

          例如(忽略[],因为你已经硬编码了)

          [(1),2,3,4] -> [1]
          [(1,2),3,4] -> [1,2]
          [(1,2,3),4] -> [1,2,3]
          [(1,2,3,4)] -> [1,2,3,4]
          [1,(2),3,4] -> [2]
          [1,(2,3),4] -> [2,3]
          [1,(2,3,4)] -> [2,3,4]
          [1,2,(3),4] -> [3]
          [1,2,(3,4)] -> [3,4]
          [1,2,3,(4)] -> [4]
          

          所以我希望[1,2,3,4] 的输出为[[],[1],[1,2],[1,2,3],[1,2,3,4],[2],[2,3],[2,3,4],[3],[3,4],[4]]

          您确实需要重新考虑您的算法。你可以试试递归。取出数组的头部(1),构造尾部的所有可能子数组([2,3]),复制它,并在其中的一半前面加上头部。当然,要构造子数组,你调用相同的函数,一直到一个空数组。

          [1,2,3] ->
          ....[2,3] ->
          ........[3] ->
          ............[] ->
          ................# an empty array is its own answer
          ................[]
          ............# duplicating the empty array and prefixing one with 3
          ............[3], []
          ........# duplicating the result from the last step and prefixing half with 2
          ........[2,3], [2], [3], []
          ....# duplicating the result from the last step and prefixing half with 1
          ....[1,2,3], [1,2], [1,3], [1], [2,3], [2], [3], []
          

          【讨论】:

          • 是的,这正是我所期望的。有什么想法吗?
          • 是的,我在算法中遗漏了一些东西,这就是我需要帮助的原因。如果使用 ([1,2,3,4]) 缺少 [1,3,4] , [2,4] 等
          猜你喜欢
          • 1970-01-01
          • 2011-08-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-02
          • 1970-01-01
          • 2016-01-08
          相关资源
          最近更新 更多