【问题标题】:Ruby, get uniq slice from combinationRuby,从组合中获取 uniq 切片
【发布时间】:2011-09-26 02:22:56
【问题描述】:

我有什么

a = [1,2,3,4]
 => [1, 2, 3, 4] 

b = a.combination(2).to_a
 => [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] 

b.each_slice(2).to_a
 => [[[1, 2], [1, 3]], [[1, 4], [2, 3]], [[2, 4], [3, 4]]] 

我想要实现的是一个独特的组合

=> [[[1, 2], [3, 4]], [[1, 4], [2, 3]], [[1, 3], [2, 4]]]

我尝试过置换、展平等。但找不到神奇的 ruby​​ 代码!

编辑:

上面的答案是这样的

b = a.combination(2).to_a
=> [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

更准确地说。

来自

a = [1,2,3,4,5,6]

如何获得

=> [[[1, 2], [3, 4], [5, 6]], [[1, 3], [2, 5], [4, 6]], [[1, 4], [2, 6], [3, 5]], [[1, 5], [2, 4], [3, 6]], [[1, 6], [2, 3], [4, 5]]]

这是 5 个 uniq 值数组 (1,2,3,4,5,6):

[1, 2], [3, 4], [5, 6]
[1, 3], [2, 5], [4, 6]
[1, 4], [2, 6], [3, 5]
[1, 5], [2, 4], [3, 6]
[1, 6], [2, 3], [4, 5]

您似乎已经改变了问题。最初你想要一个数组数组,每个数组都有一对数组。现在你想要三胞胎吗?

是的,因为 [1,2,3,4] 的第一个示例太简单了,而且答案不适合更复杂的数组,例如 [1,2,3,4,5,6] 和所以一个。

【问题讨论】:

  • 这个问题非常模糊。
  • 你似乎改变了问题。最初你想要一个数组数组,每个数组都有一对数组。现在你想要三胞胎吗?

标签: ruby arrays combinations slice uniq


【解决方案1】:

将此作为另一个答案添加,因为这确实是一个稍微不同的问题 - 而且难度更大!

 def accept(a)
   0.upto(a.size-1){|i| return false unless a[i] == a[i].sort
   return false if (i > 0 && a[i][0] <= a[i-1][0])}
   true
end

 x=[1,2,3,4,5,6].permutation.inject([]){|arr, per| arr<< per.in_groups_of(2); arr}
 arr = x.inject([]){|arr,y| arr << y if accept(y); arr}
 p arr

不是很漂亮,但是对于我认为的任何大小的数组都可以满足您的需求

【讨论】:

  • 这会给出很多重复的数组,例如 [1, 2]。我想要的是这个数组 uniq,就像我写的例子一样。
  • 实际上,最后一行的 print 语句会打印出您想要的内容 - 进行编辑以使其更清晰 - 在控制台中,这被随后的输出所淹没
【解决方案2】:

最后我找到了一个没有排列、唯一、组合、展平的解决方案:)

    a = [1,2,3,4,5,6]
    count = a.count

    totalloop = count - 1
    arrayperloop = count / 2
    rounds = []

    for round in 0...totalloop
        for i in 0...arrayperloop

            x = (round + i) % (count - 1)
            y = (count - 1 - i + round) % (count - 1)

            if i == 0
              y = count - 1
            end

            rounds<<[x + 1, y + 1]
        end
    end

rounds.each_slice(arrayperloop).to_a 给我我想要的

    [[[1, 6], [2, 5], [3, 4]], [[2, 6], [3, 1], [4, 5]], [[3, 6], [4, 2], [5, 1]], [[4, 6], [5, 3], [1, 2]], [[5, 6], [1, 4], [2, 3]]]

没那么丑!如果我们将 n*2 整数添加到数组中,则始终有效。

【讨论】:

  • 你没有使用a。您可以将前两行替换为count = 6
【解决方案3】:

嗯,它不漂亮,但它有效。组合需要一个块。

a = [1,2,3,4]
ans = []

a.combination(2) do |i|
  a.combination(2) do |j|
    x = [i, j]
    y = x.flatten
    next if y.uniq != y
    ans << x
  end
end

puts ans.inspect

编辑:让它稍微不那么难看。

【讨论】:

    【解决方案4】:

    我认为这可以让您了解大部分情况

    [1,2,3,4].combination(2).inject([]){|arr,r| arr &lt;&lt; (Hash[*r]); arr}

    如果你迭代地从这个数组中取出第一个和最后一个元素,你会得到你想要的

    def con(h, arr = []) 
      arr <<[h.delete(h.first).to_a.flatten, h.delete(h.last).to_a.flatten]
      con(h, arr) unless h.empty?
      p arr
    end
    
    #=> [[[1, 2], [3, 4]], [[1, 3], [2, 4]], [[1, 4], [2, 3]]]
    

    【讨论】:

      猜你喜欢
      • 2012-09-11
      • 1970-01-01
      • 2018-03-22
      • 2021-10-23
      • 2020-07-19
      • 1970-01-01
      • 2021-08-26
      • 2011-04-03
      • 1970-01-01
      相关资源
      最近更新 更多