Files
go-pkg/maths/factorial.go
2022-03-10 11:47:35 +08:00

91 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package maths
func factorial(m int) (n int) {
n = 1
for i := 2; i <= m; i++ {
n *= i
}
return
}
// permutation (n, m)的排列情况(从n个数中取m个数进行排列)
func permutation(n, m int) (data int) {
data = factorial(n) / factorial(m)
return
}
// combination (n,m)的组合情况(从n个数中取m个进行组合)
func combination(n, m int) (data int) {
data = factorial(n) / (factorial(n-m) * factorial(m))
return
}
// Combination 从src中选取length个元素出来
// 组合是一个基本的数学问题本程序的目标是输出从n个元素中取m个的所有组合。
// 例如从[1,2,3]中取出2个数一共有3中组合[1,2],[1,3],[2,3]。(组合不考虑顺序,即[1,2]和[2,1]属同一个组合)
// 从n中选取m个组合
// 例如: 从make([]int, 10)中选取5个元素的所有组合此时n=10, m=5
// 返回的combination为为每个元素的索引组成的二维切片
func Combination(n, m int) (combs [][]int) {
//1创建有n个元素数组数组元素的值为1表示选中为0则没选中。
//2初始化将数组前m个元素置1表示第一个组合为前m个数。
//3从左到右扫描数组元素值的“10”组合找到第一个“10”组合后将其变为“01”组合同时将其左边的所有“1”全部移动到数组的最左端。
//4当某次循环没有找到“10“组合时说明得到了最后一个组合循环结束。
if n < m || m < 1 {
return
}
// cap直接根据公式计算得出
combs = make([][]int, 0, combination(n, m))
// 初始化n个元素前m个置为1其余置为0
idx := make([]int, n)
for i := 0; i < m; i++ {
idx[i] = 1
}
// 第一种情况添加进结果集合
add(&combs, idx)
for {
flag := false
for i := 0; i < n-1; i++ {
if idx[i] == 1 && idx[i+1] == 0 {
flag = true
idx[i], idx[i+1] = idx[i+1], idx[i]
if i > 1 {
moveToLeft(idx[:i])
}
add(&combs, idx)
break
}
}
if !flag {
break
}
}
return
}
func add(dst *[][]int, ele []int) {
data := make([]int, len(ele))
copy(data, ele)
*dst = append(*dst, data)
}
func moveToLeft(s []int) {
sum := 0
for i := 0; i < len(s); i++ {
if s[i] == 1 {
sum++
}
}
for i := 0; i < len(s); i++ {
if i < sum {
s[i] = 1
} else {
s[i] = 0
}
}
}