これって組み込み関数がないのですかねえ...
順列。コード。
permutation.go
package main import "fmt" //スライスの 位置 i の要素を除いたスライスを返す(arを破壊しないようコピーしている) func remove(ar []int, i int) []int { tmp := make([]int, len(ar)) copy(tmp, ar) return append(tmp[0:i], tmp[i + 1:]...) } func permutation(ar []int) [][]int { var result [][]int if len(ar) == 1 {return append(result, ar)} for i, a := range ar { for _, b := range permutation(remove(ar, i)) { result = append(result, append([]int{a}, b...)) } } return result } func main() { fmt.Println(permutation([]int{50, 2, 1, 9})) }
結果。
[[50 2 1 9] [50 2 9 1] [50 1 2 9] [50 1 9 2] [50 9 2 1] [50 9 1 2] [2 50 1 9] [2 50 9 1] [2 1 50 9] [2 1 9 50] [2 9 50 1] [2 9 1 50] [1 50 2 9] [1 50 9 2] [1 2 50 9] [1 2 9 50] [1 9 50 2] [1 9 2 50] [9 50 2 1] [9 50 1 2] [9 2 50 1] [9 2 1 50] [9 1 50 2] [9 1 2 50]]
ちなみにこれは Ruby では
def permutation(ar) result = [] return [ar] if ar.size == 1 ar.each_with_index do |a, i| permutation(ar[0, i] + ar[i + 1..-1]).each do |b| result += [[a] + b] end end result end p permutation([50, 2, 1, 9])
で同等。あるいは組み込み関数を使って
p [50, 2, 1, 9].permutation.to_a
でおしまい。
要素数を指定した順列、組み合わせ
package main import "fmt" func remove(ar []int, i int) []int { tmp := make([]int, len(ar)) copy(tmp, ar) return append(tmp[0:i], tmp[i + 1:]...) } func permutation_full(ar []int) [][]int { var result [][]int if len(ar) == 1 {return append(result, ar)} for i, a := range ar { for _, b := range permutation_full(remove(ar, i)) { result = append(result, append([]int{a}, b...)) } } return result } //順列 func permutation(ar []int, n int) (result [][]int) { for _, a := range combination(ar, n) { result = append(result, permutation_full(a)...) } return } //組み合わせ func combination(ar []int, n int) (result [][]int) { if n <= 0 || len(ar) < n {return} if n == 1 { for _, a := range ar { result = append(result, []int{a}) } } else if len(ar) == n { result = append(result, ar) } else { for _, a := range combination(ar[1:], n - 1) { result = append(result, append([]int{ar[0]}, a...)) } result = append(result, combination(ar[1:], n)...) } return } func main() { fmt.Println(combination([]int{50, 2, 1, 9}, 3)) fmt.Println(permutation([]int{50, 2, 1, 9}, 3)) }
組み合わせの場合が結構複雑になったのだけれど、もっといいやり方はないかな。
結果。
[[50 2 1] [50 2 9] [50 1 9] [2 1 9]] [[50 2 1] [50 1 2] [2 50 1] [2 1 50] [1 50 2] [1 2 50] [50 2 9] [50 9 2] [2 50 9] [2 9 50] [9 50 2] [9 2 50] [50 1 9] [50 9 1] [1 50 9] [1 9 50] [9 50 1] [9 1 50] [2 1 9] [2 9 1] [1 2 9] [1 9 2] [9 2 1] [9 1 2]]
[]int
はお好みの型でどうぞ。Go は [[]]
という配列は作れないのだな。ああ、[]interface{}{[]int{}}
とかはできるか。
しかしこれ、C でやったら大変そう。どうやってやるのだろう。