feat(Go-Tool):2021/03/26: 新增全排列的递归实现、字典序实现、递增进制位实现、递减进制位实现
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/22 15:29
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
import (
|
||||
sort2 "Go-Tool/util/sort"
|
||||
)
|
||||
|
||||
//字典序获取全排列
|
||||
func (per *Permutation) DictionaryOrder(b []byte) {
|
||||
//先排序
|
||||
sort2.QuickSortByte(b, 0, len(b)-1)
|
||||
for {
|
||||
bef := 0
|
||||
afr := 0
|
||||
result := make([]byte, len(b))
|
||||
copy(result, b)
|
||||
per.bytes = append(per.bytes, result)
|
||||
|
||||
//从右往左找到第一个左边比右边小的数字
|
||||
for bef = len(b) - 2; ; bef-- {
|
||||
if bef < 0 {
|
||||
return
|
||||
}
|
||||
if b[bef] < b[bef+1] {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//知道q的位置之后
|
||||
//从q开始向右边查找比位置q的数字大的第一个数字的位置
|
||||
for afr = len(b) - 1; afr > 0; afr-- {
|
||||
if b[afr] > b[bef] {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//交换两个数字
|
||||
b[bef], b[afr] = b[afr], b[bef]
|
||||
//把后面的数字进行转置成递增顺序
|
||||
b = per.Reverse(b, bef+1, len(b)-1)
|
||||
}
|
||||
}
|
||||
|
||||
func (per *Permutation) Reverse(b []byte, start, end int) []byte {
|
||||
for start <= end {
|
||||
b[start], b[end] = b[end], b[start]
|
||||
start++
|
||||
end--
|
||||
}
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/22 15:29
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDictionaryOrder(t *testing.T) {
|
||||
p := NewPermutation()
|
||||
|
||||
p.DictionaryOrder([]byte("1234"))
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.DictionaryOrder([]byte("12345"))
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.DictionaryOrder([]byte("abcde"))
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.DictionaryOrder([]byte("abcdea"))
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
}
|
||||
|
||||
func TestPermutation_Reverse(t *testing.T) {
|
||||
p := NewPermutation()
|
||||
fmt.Println(p.Reverse([]byte{1, 2, 3, 4}, 0, 3))
|
||||
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5}, 0, 4))
|
||||
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5, 6}, 0, 5))
|
||||
fmt.Println(p.Reverse([]byte{1, 2, 3, 4, 5, 6, 7}, 0, 6))
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/23 17:06
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
func DigitDecreases(b []int) [][]int {
|
||||
result := make([][]int, 0)
|
||||
bit := make([]int, len(b)-1)
|
||||
sum := 1
|
||||
//计算中的结果数,阶乘
|
||||
for i := 1; i <= len(b); i++ {
|
||||
sum = sum * i
|
||||
}
|
||||
for i := 0; i < sum; i++ {
|
||||
result = append(result, getRangeBySpace1(b, bit))
|
||||
bit = decreaseBit(bit)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
//根据递增进制位,并且根据【数空格法】在原来的数组中求得全排列的一种可能实现
|
||||
//origin 原始数组
|
||||
//increaseBit 递增进制位,比原始数组长度小1,这里通过数组实现,更简单
|
||||
func getRangeBySpace1(origin []int, increaseBit []int) []int {
|
||||
permutation := make([]int, len(origin))
|
||||
flag := make(map[int]bool, 0)
|
||||
//排列数组从左往右,即从大到小
|
||||
for i := 0; i < len(origin)-1; i++ {
|
||||
p := increaseBit[i] //从右到左,对应数字应该填充的位置
|
||||
j := len(origin) - 1 //该数字在本次排列的位置
|
||||
for ; ; j-- {
|
||||
//该位置未被填充
|
||||
if !flag[j] {
|
||||
p--
|
||||
}
|
||||
//找到对应位置需要推出循环
|
||||
if p < 0 {
|
||||
flag[j] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
permutation[j] = origin[i]
|
||||
}
|
||||
for i := 0; i < len(origin); i++ {
|
||||
if !flag[i] {
|
||||
permutation[i] = origin[len(origin)-1]
|
||||
}
|
||||
}
|
||||
|
||||
return permutation
|
||||
}
|
||||
|
||||
//递减进制位
|
||||
//每次加一,计算新的数组结果
|
||||
func decreaseBit(bit []int) []int {
|
||||
|
||||
//数组下标从小到大,进制位从大到小
|
||||
for i := 0; i < len(bit); i++ {
|
||||
if bit[i]+1 >= len(bit)+1-i {
|
||||
bit[i] = (bit[i] + 1) % (len(bit) + 1 - i)
|
||||
} else {
|
||||
bit[i] += 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return bit
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/23 19:53
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDecreaseBit(t *testing.T) {
|
||||
|
||||
bit := []int{0, 0}
|
||||
for i := 0; i < 6; i++ {
|
||||
fmt.Println(bit)
|
||||
bit = decreaseBit(bit)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
bit = []int{0, 0, 0}
|
||||
for i := 0; i < 24; i++ {
|
||||
fmt.Println(bit)
|
||||
bit = decreaseBit(bit)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
bit = []int{0, 0, 0, 0}
|
||||
for i := 0; i < 120; i++ {
|
||||
fmt.Print(bit)
|
||||
bit = decreaseBit(bit)
|
||||
}
|
||||
|
||||
}
|
||||
func TestGetRangeBySpace1(t *testing.T) {
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{0, 0}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{1, 0}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{2, 0}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{0, 1}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{1, 1}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3}, []int{2, 1}))
|
||||
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 0}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 1}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{4, 3, 2, 1}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{3, 0, 0, 0}))
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5}, []int{1, 3, 2, 1}))
|
||||
|
||||
fmt.Println(getRangeBySpace1([]int{1, 2, 3, 4, 5, 6, 7}, []int{3, 4, 2, 2, 2, 1}))
|
||||
}
|
||||
|
||||
func TestDigitDecrease(t *testing.T) {
|
||||
fmt.Println(DigitDecreases([]int{1, 2, 3}))
|
||||
fmt.Println(DigitDecreases([]int{20, 50, 30, 67}))
|
||||
fmt.Println(DigitDecreases([]int{20, 50, 30, 99, 18213}))
|
||||
fmt.Println(DigitDecreases([]int{20, 50, 30, 78321, 2321, 432}))
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/23 17:05
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
func DigitIncrease(b []int) [][]int {
|
||||
result := make([][]int, 0)
|
||||
bit := make([]int, len(b)-1)
|
||||
sum := 1
|
||||
//计算中的结果数,阶乘
|
||||
for i := 1; i <= len(b); i++ {
|
||||
sum = sum * i
|
||||
}
|
||||
for i := 0; i < sum; i++ {
|
||||
result = append(result, getRangeBySpace(b, bit))
|
||||
bit = increaseBit(bit)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
//根据递增进制位,并且根据【数空格法】在原来的数组中求得全排列的一种可能实现
|
||||
//origin 原始数组
|
||||
//increaseBit 递增进制位,比原始数组长度小1,这里通过数组实现,更简单
|
||||
func getRangeBySpace(origin []int, increaseBit []int) []int {
|
||||
permutation := make([]int, len(origin))
|
||||
flag := make(map[int]bool, 0)
|
||||
//排列数组从左往右,即从大到小
|
||||
for i := len(origin) - 1; i > 0; i-- {
|
||||
p := increaseBit[i-1] //从右到左,对应数字应该填充的位置
|
||||
j := len(origin) - 1 //该数字在本次排列的位置
|
||||
//中介数计算从左到右,即从大到小
|
||||
for ; ; j-- {
|
||||
//该位置未被填充
|
||||
if !flag[j] {
|
||||
p--
|
||||
}
|
||||
//找到对应位置需要推出循环
|
||||
if p < 0 {
|
||||
flag[j] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
permutation[j] = origin[i]
|
||||
}
|
||||
for i := 0; i < len(origin); i++ {
|
||||
if !flag[i] {
|
||||
permutation[i] = origin[0]
|
||||
}
|
||||
}
|
||||
|
||||
return permutation
|
||||
}
|
||||
|
||||
//递增进制位
|
||||
//根据递增进制位进行+1操作,返回递增的结果
|
||||
func increaseBit(bit []int) []int {
|
||||
//最开始是从二进制开始
|
||||
for i, num := range bit {
|
||||
if num+1 >= i+2 {
|
||||
bit[i] = (num + 1) % (i + 2)
|
||||
} else {
|
||||
bit[i] = num + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return bit
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/23 19:54
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetRangeBySpace(t *testing.T) {
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 0})) //123
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 0})) //
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 1})) //
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 1})) //
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{0, 2})) //
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3}, []int{1, 2})) //321
|
||||
|
||||
//fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 0})) //12345
|
||||
//fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 1})) //21354
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4})) //54321
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{0, 0, 0, 3})) //12534
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 1})) //43251
|
||||
|
||||
fmt.Println(getRangeBySpace([]int{1, 2, 3, 4, 5, 6, 7}, []int{1, 2, 2, 2, 4, 3})) //3647521
|
||||
}
|
||||
|
||||
func TestIncreaseBit(t *testing.T) {
|
||||
bit := []int{0, 0}
|
||||
for i := 0; i < 6; i++ {
|
||||
fmt.Println(bit)
|
||||
bit = increaseBit(bit)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
bit = []int{0, 0, 0, 0}
|
||||
for i := 0; i < 120; i++ {
|
||||
bit = increaseBit(bit)
|
||||
fmt.Println(bit)
|
||||
}
|
||||
|
||||
bit = []int{0, 0, 0}
|
||||
for i := 0; i < 24; i++ {
|
||||
bit = increaseBit(bit)
|
||||
fmt.Println(bit)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDigitIncrease(t *testing.T) {
|
||||
fmt.Println(DigitIncrease([]int{1, 2, 3}))
|
||||
fmt.Println(DigitIncrease([]int{20, 50, 30, 67}))
|
||||
fmt.Println(DigitIncrease([]int{20, 50, 30, 99, 18213}))
|
||||
fmt.Println(DigitIncrease([]int{20, 50, 30, 78321, 2321, 432}))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/22 11:09
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
type Permutation struct {
|
||||
bytes [][]byte
|
||||
}
|
||||
|
||||
func NewPermutation() *Permutation {
|
||||
return &Permutation{
|
||||
bytes: [][]byte{},
|
||||
}
|
||||
}
|
||||
|
||||
func (per *Permutation) Recursion(b []byte, start int) {
|
||||
//递归交换到最后一个位置结束
|
||||
if start == len(b)-1 {
|
||||
bCopy := make([]byte, len(b))
|
||||
copy(bCopy, b)
|
||||
per.bytes = append(per.bytes, bCopy)
|
||||
}
|
||||
|
||||
for i := start; i < len(b); i++ {
|
||||
//交换固定位置
|
||||
b[i], b[start] = b[start], b[i]
|
||||
//固定某一个数字位置,递归后面的其他数字
|
||||
per.Recursion(b, start+1)
|
||||
//还原固定位置,进行下一次操作
|
||||
b[i], b[start] = b[start], b[i]
|
||||
}
|
||||
}
|
||||
|
||||
func (per *Permutation) Reset() {
|
||||
per.bytes = [][]byte{}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2021/3/22 11:22
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package FullPermutation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRecursion(t *testing.T) {
|
||||
p := NewPermutation()
|
||||
|
||||
p.Recursion([]byte("123"), 0)
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.Recursion([]byte("12345"), 0)
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.Recursion([]byte("abcde"), 0)
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
p.Recursion([]byte("abcdea"), 0)
|
||||
fmt.Println()
|
||||
for _, bs := range p.bytes {
|
||||
fmt.Println(string(bs))
|
||||
}
|
||||
p.Reset()
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user