Groovy中的真正组合

时间:2014-10-09 07:42:52

标签: groovy combinatorics

是否有方法或智能方法易于阅读以在Groovy中生成combination个元素?我知道Iterable#combinationsGroovyCollections#combinations,但是到目前为止我已经了解了重复的部分排列。见例。

// Groovy combinations result
def e = ['a', 'b', 'c']
def result = [e, e].combinations()
assert [['a', 'a'], ['b', 'a'], ['c', 'a'], ['a', 'b'], ['b', 'b'], ['c', 'b'], ['a','c'], ['b', 'c'], ['c', 'c']] == result

// What I'm looking for
def e = ['a', 'b', 'c']
def result = ???
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result
  

随意发布替代解决方案。我仍在寻找更好的可读性(在非开发人员的脚本中使用)和性能(没有不必要的迭代)。

2 个答案:

答案 0 :(得分:11)

我对可读性不太确定,但这应该可行。

def e = ['a', 'b', 'c']
def result = [e, e].combinations().findAll { a, b ->
    a < b
}

assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result

请注意,如果元素在列表中出现两次,则其组合也会出现两次。如果不需要的话,最后添加'.unique()'

答案 1 :(得分:7)

这是一种更通用的方法,允许您为nCr组合指定“r”值。它通过在集合中存储排列来实现这一点,其中集合提供唯一性:

// returns combinations of the input list of the provided size, r
List combinationsOf(List list, int r) {
    assert (0..<list.size()).contains(r) // validate input
    def combs = [] as Set
    list.eachPermutation {
        combs << it.subList(0, r).sort { a, b -> a <=> b }
    }
    combs as List
}

// the test scenario...
def e = ['a', 'b', 'c']
def result = combinationsOf(e, 2)
assert [['a', 'b'], ['a', 'c'], ['b', 'c']] == result