查找数组中的所有子集

时间:2013-11-18 12:09:30

标签: ruby arrays string algorithm numbers

我需要帮助解决这个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

我的结果==&gt; [[], ["1"], ["1", "2"], ["1", "2", "3"], ["2"], ["2", "3"], ["3"]。我的问题是我错过了一个结果["1", "3"]

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

5 个答案:

答案 0 :(得分: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]]

答案 1 :(得分:1)

看起来你正在查看数组中的某个起点,然后查看从该起点开始的所有子数组,然后将起点向下移动。这样,你就会错过带有间隙的子阵列。对于[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], []

答案 2 :(得分:1)

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

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]]

答案 3 :(得分:0)

我的解决方案。

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

具有少一个元素的数组的子集 - 让我们调用这些旧的子集

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

例如 -

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

子集([1,2]) - old_subsets

为每个old_subsets添加3个

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

答案 4 :(得分:0)

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

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]]