小编典典

在go中生成所有排列

go

我正在寻找一种生成元素列表的所有可能排列的方法。类似于python的
itertools.permutations(arr)

permutations ([])
[]

permutations ([1])
[1]

permutations ([1,2])
[1, 2]
[2, 1]

permutations ([1,2,3])
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]

区别在于我不在乎排列是按需生成(例如python中的生成器)还是全部生成。我也不关心它们是否按字典顺序排序。我所需要做的就是以某种方式获得这些n!排列。


阅读 242

收藏
2020-07-02

共1个答案

小编典典

产生置换的算法很多。我发现的最简单的方法之一是堆算法

通过选择一对要交换的元素,它会根据前一个生成每个排列。

在上面的链接中概述了这个想法和一个伪代码一个接一个地打印排列。这是我实现的算法的实现,该算法返回所有排列

func permutations(arr []int)[][]int{
    var helper func([]int, int)
    res := [][]int{}

    helper = func(arr []int, n int){
        if n == 1{
            tmp := make([]int, len(arr))
            copy(tmp, arr)
            res = append(res, tmp)
        } else {
            for i := 0; i < n; i++{
                helper(arr, n - 1)
                if n % 2 == 1{
                    tmp := arr[i]
                    arr[i] = arr[n - 1]
                    arr[n - 1] = tmp
                } else {
                    tmp := arr[0]
                    arr[0] = arr[n - 1]
                    arr[n - 1] = tmp
                }
            }
        }
    }
    helper(arr, len(arr))
    return res
}

以下是使用方法的示例(转到Playground):

arr := []int{1, 2, 3}
fmt.Println(permutations(arr))
[[1 2 3] [2 1 3] [3 2 1] [2 3 1] [3 1 2] [1 3 2]]

需要注意的一件事是,排列不是按字典顺序排序的(如您在中所见itertools.permutations)。如果出于某种原因需要对它进行排序,我发现它的一种方法是从阶乘数系统生成它们(在中进行了描述,permutation section并允许快速找到第n个字典编排)。

PS,
您也可以在这里这里看看其他人的代码

2020-07-02