Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ba69e98d5 | |||
| 092ab58276 | |||
| 00ada130fa | |||
| 8dbfebe5be | |||
| 1aa86ce5b8 | |||
| ed71f9b607 | |||
| 351df675bd | |||
| dc5d924a2c | |||
| 74dd19c675 | |||
| 39cee0ce6a |
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:46
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package numberList
|
||||||
|
|
||||||
|
type i interface {
|
||||||
|
Doc() string
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/18 13:08
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberOtherKObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberOtherKObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个整型数组 arr和一个大于1的整数k。已知 arr中只有1个数出现了1次,其他的数都出现了k次,请返回只出现了1次的数。
|
||||||
|
|
||||||
|
【要求】
时间复杂度为 O(N),额外空间复杂度为 O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyOneNumberOtherK(numList []int, k int) int {
|
||||||
|
bitList := make([]int, 32)
|
||||||
|
for _, num := range numList {
|
||||||
|
//把每个数字转换成二进制
|
||||||
|
store := make([]int, 32)
|
||||||
|
for i := 0; num != 0; i++ {
|
||||||
|
store[i] = num % k
|
||||||
|
num = num / k
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < 32; j++ {
|
||||||
|
//不进位加法
|
||||||
|
bitList[j] = (store[j] + bitList[j]) % k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//k进制转换回十进制
|
||||||
|
power := 1 //k的次方值
|
||||||
|
result := 0 //只出现一次的数字
|
||||||
|
for i, bit := range bitList {
|
||||||
|
power = 1
|
||||||
|
for j := 0; j < i; j++ {
|
||||||
|
power = power * k
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result + power*bit
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/18 13:09
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherK(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 2, 3, 4}, 2)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 2, 3, 4, 2, 3, 4}, 3)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 3, 4, 4, 5, 6, 2, 2, 3, 5, 5, 3, 4, 6, 6}, 3)) //1
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, 10)) //1
|
||||||
|
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 3000, 4, 2, 3, 4}, 2)) //3000
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 4, 2, 9999, 3, 4, 2, 3, 4}, 3)) //9999
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 3, 4, 4, 5, 6, 321, 2, 2, 3, 5, 5, 3, 4, 6, 6}, 3)) //321
|
||||||
|
fmt.Println(OnlyOneNumberOtherK([]int{2, 2, 2, 2, 2, 2, 2, 5891, 2, 2, 2}, 10)) //5891
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 21:53
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberOtherThreeObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberOtherThreeObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
|
||||||
|
要求:线性时间复杂度。 不使用额外空间来实现
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyOneNumberOtherThree1(numList []int) int {
|
||||||
|
bitList := make([]int, 32)
|
||||||
|
|
||||||
|
for _, num := range numList {
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
bitList[i] += (num >> i) & 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res := 0
|
||||||
|
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
if bitList[i]%3 != 0 {
|
||||||
|
res += 1 << i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过二进制的方式,本质上就是要构造一个相应的回路,即出现num的次数分别从1~3应该是 01 -> 10 -> 00 ...
|
||||||
|
func OnlyOneNumberOtherThree2(numList []int) int {
|
||||||
|
|
||||||
|
var a uint
|
||||||
|
var b uint
|
||||||
|
|
||||||
|
//第一次出现num计算的结果 a = num ,b = 0
|
||||||
|
//第二次出现num计算的结果 a = 0 ,b = num
|
||||||
|
//第三次出现num计算的结果 a = num ,b = 0
|
||||||
|
//因此直接返回a即可
|
||||||
|
for _, num := range numList {
|
||||||
|
a = a ^ uint(num)&(^b)
|
||||||
|
b = b ^ uint(num)&(^a)
|
||||||
|
}
|
||||||
|
return int(a)
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 21:55
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherThree1(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 1, 1, 2, 2, 2, 3, 3, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{1, 15, 23, 67, 15, 67, 67, 23, 23, 14, 15, 1, 1})) //14
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree1([]int{100, 200, 300, 4, 6, 100, 100, 6, 6, 4, 200, 300, 200, 300, 5, 4})) //5
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnlyOneNumberOtherThree2(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 1, 1, 2, 2, 2, 3, 3, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 4})) //4
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{1, 15, 23, 67, 15, 67, 67, 23, 23, 14, 15, 1, 1})) //14
|
||||||
|
fmt.Println(OnlyOneNumberOtherThree2([]int{100, 200, 300, 4, 6, 100, 100, 6, 6, 4, 200, 300, 200, 300, 5, 4})) //5
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 17:51
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyOneNumberShowOnceObj struct{}
|
||||||
|
|
||||||
|
func (*OnlyOneNumberShowOnceObj) Doc() string {
|
||||||
|
return `
|
||||||
|
一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过异或解决
|
||||||
|
func OnlyOneNumberShowOnce(numberList []int) int {
|
||||||
|
result := 0
|
||||||
|
for _, num := range numberList {
|
||||||
|
result ^= num
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 17:52
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyOneNumberShowOnce(t *testing.T) {
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4})) //1
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4, 1, 5})) //5
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{1, 2, 3, 2, 3, 4, 4, 1, 10})) //10
|
||||||
|
fmt.Println(OnlyOneNumberShowOnce([]int{2, 2, 2, 2, 1, 3, 3, 3, 3})) //1
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 18:01
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
type OnlyTwoNumberShowOnceObj struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*OnlyTwoNumberShowOnceObj) Doc() string {
|
||||||
|
return `
|
||||||
|
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnlyTwoNumberShowOnce(numList []int) (int, int) {
|
||||||
|
if len(numList) < 2 {
|
||||||
|
panic("数组长度不能小于两个")
|
||||||
|
}
|
||||||
|
result := 0
|
||||||
|
//先进行异或,得到异或的结果
|
||||||
|
for _, num := range numList {
|
||||||
|
result = result ^ num
|
||||||
|
}
|
||||||
|
//找到异或后为1的位置
|
||||||
|
pos := 0
|
||||||
|
for ; pos < 32; pos++ {
|
||||||
|
if ((result >> pos) & 1) == 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstList := make([]int, 0)
|
||||||
|
secondList := make([]int, 0)
|
||||||
|
|
||||||
|
//根据异或位的结果,把数组分成两组
|
||||||
|
for _, num := range numList {
|
||||||
|
if ((num >> pos) & 1) == 1 {
|
||||||
|
firstList = append(firstList, num)
|
||||||
|
} else {
|
||||||
|
secondList = append(secondList, num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
first := 0
|
||||||
|
for _, num := range firstList {
|
||||||
|
first ^= num
|
||||||
|
}
|
||||||
|
second := 0
|
||||||
|
|
||||||
|
for _, num := range secondList {
|
||||||
|
second ^= num
|
||||||
|
}
|
||||||
|
|
||||||
|
return first, second
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 18:02
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberCount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOnlyTwoNumberShowOnce(t *testing.T) {
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7, 8, 9, 0, 19, 19, 0, 8, 9})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 1, 7, 5, 4, 3, 2})) //1,7
|
||||||
|
fmt.Println(OnlyTwoNumberShowOnce([]int{2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 1, 7, 1, 100})) //1,100
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 15:45
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
type NumberMoreThanHalfObj struct{}
|
||||||
|
|
||||||
|
func (n *NumberMoreThanHalfObj) Doc() string {
|
||||||
|
return `
|
||||||
|
题目:
|
||||||
|
|
||||||
|
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
|
||||||
|
|
||||||
|
例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
|
||||||
|
|
||||||
|
要求:时间复杂度O(N),空间复杂度O(1)
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NumberMoreThanHalf(numList []int) int {
|
||||||
|
var number, count int
|
||||||
|
for _, j := range numList {
|
||||||
|
if number == j {
|
||||||
|
count++
|
||||||
|
} else if number != j && count <= 1 {
|
||||||
|
number = j
|
||||||
|
} else {
|
||||||
|
//number !=j && count >1
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//最后验证,确保一定超过
|
||||||
|
countValid := 0
|
||||||
|
for _, j := range numList {
|
||||||
|
if j == number {
|
||||||
|
countValid++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if countValid <= len(numList)/2 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return number
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:23
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNumberMoreThanHalf(t *testing.T) {
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 1, 1})) //1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 1})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 2, 3, 2, 3, 3})) //-1
|
||||||
|
fmt.Println(NumberMoreThanHalf([]int{1, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1})) //1
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:46
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
type NumberMoreThanKObj struct{}
|
||||||
|
|
||||||
|
func (*NumberMoreThanKObj) Doc() string {
|
||||||
|
return `
|
||||||
|
给定一个整型数组arr(数组长度为N) 与一个整数k,打印所有出现次数大于 N/K 的数。如果没有这样的数,返回-1。
|
||||||
|
|
||||||
|
要求:时间复杂度为O(N*K),额外空间复杂度为O(K)。
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NumberMoreThanK(numList []int, k int) []int {
|
||||||
|
//小于2的情况是肯定不会超过.
|
||||||
|
if k < 2 {
|
||||||
|
return []int{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//用来保存数字与其出现次数
|
||||||
|
numMap := make(map[int]int, 0)
|
||||||
|
for _, num := range numList {
|
||||||
|
//如果不存在则数值设置为1
|
||||||
|
if _, ok := numMap[num]; !ok {
|
||||||
|
numMap[num] = 1
|
||||||
|
} else {
|
||||||
|
//存在则出现次数+1
|
||||||
|
numMap[num] = numMap[num] + 1
|
||||||
|
}
|
||||||
|
//当容器的大小为k
|
||||||
|
if len(numMap) == k {
|
||||||
|
for key, value := range numMap {
|
||||||
|
//个数正好等于1的要删掉,因为本次减一之后,就等于0了
|
||||||
|
if value == 1 {
|
||||||
|
delete(numMap, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//map的key是可能出现次数超过N/k的数
|
||||||
|
//这里主要是为了拿到key
|
||||||
|
for key := range numMap {
|
||||||
|
numMap[key] = 0
|
||||||
|
}
|
||||||
|
//重新计算对应数字的出现次数
|
||||||
|
for _, num := range numList {
|
||||||
|
if _, ok := numMap[num]; ok {
|
||||||
|
numMap[num]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//出现次数超过k次的判断
|
||||||
|
result := make([]int, 0)
|
||||||
|
for key, value := range numMap {
|
||||||
|
if value > len(numList)/k {
|
||||||
|
result = append(result, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/16 16:59
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package NumberMoreThan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNumberMoreThanK(t *testing.T) {
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}, 3)) //1
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}, 4)) //1,2,3
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3, 1, 2, 3, 1, 2, 3}, 2)) //
|
||||||
|
fmt.Println(NumberMoreThanK([]int{1, 2, 3}, 2)) //
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#我的公众号二维码
|
||||||
|

|
||||||
|
|
||||||
# 作用
|
# 作用
|
||||||
本工程仅供个人学习记录,刚开始学习go(之前是java),本工程积累一些反射的用法。后期查询更加快捷
|
本工程仅供个人学习记录,刚开始学习go(之前是java),本工程积累一些反射的用法。后期查询更加快捷
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@
|
|||||||
|
|
||||||
2020/11/25:完善linq包使用示例
|
2020/11/25:完善linq包使用示例
|
||||||
|
|
||||||
2020/12/7 :更新bit位操作工作 BitTool
|
2020/12/7 : 更新bit位操作工作 BitTool
|
||||||
|
|
||||||
2020/12/15:添加前缀树工具,实现前缀搜索和字符串搜索功能
|
2020/12/15:添加前缀树工具,实现前缀搜索和字符串搜索功能
|
||||||
|
|
||||||
@@ -68,7 +71,19 @@
|
|||||||
|
|
||||||
2020/12/31:新增项目案例(角色技能树)
|
2020/12/31:新增项目案例(角色技能树)
|
||||||
|
|
||||||
2021/2/5: 新增二分查找区间内数值方法
|
2021/02/05: 新增二分查找区间内数值方法
|
||||||
|
|
||||||
|
2021/03/02: 新增字符串匹配 暴力匹配、KMP匹配、SunDay匹配算法
|
||||||
|
|
||||||
|
2021/03/11: 新增Kr、Shift and/or字符串匹配算法
|
||||||
|
|
||||||
|
2021/03/14: 新增Manacher算法,求最长回文串
|
||||||
|
|
||||||
|
2021/03/18:新增超过半数数字系列算法题,新增出现次数不同的数字系列算法题
|
||||||
|
|
||||||
|
2021/03/26: 新增全排列的递归实现、字典序实现、递增进制位实现、递减进制位实现
|
||||||
|
|
||||||
|
2021/06/16 新增一个数拆分成N个数且N个数相加和等于这个数工具、测试方法
|
||||||
|
|
||||||
# 修复日志
|
# 修复日志
|
||||||
2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
|
2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组)
|
||||||
@@ -79,7 +94,13 @@
|
|||||||
|
|
||||||
2020/12/31:删除源码学习部分,挪到Go-Study工程
|
2020/12/31:删除源码学习部分,挪到Go-Study工程
|
||||||
|
|
||||||
2021/1/4 :reflectM包添加indirect处理指针和非指针,获取type、value
|
2021/01/04:reflectM包添加indirect处理指针和非指针,获取type、value
|
||||||
|
|
||||||
|
2021/02/18:bitStore新增特殊档位获取方法,修改档位数目的参数标识
|
||||||
|
|
||||||
|
2021/02/23: 删除linq包使用示例,修改二进制工具与单测类,修改lomuto划分,修改前缀树与单测类,修改时间比较工具
|
||||||
|
|
||||||
|
2021/03/02: 修复Rand包随机获取方法
|
||||||
|
|
||||||
# mod vendor模式加载包
|
# mod vendor模式加载包
|
||||||
通过go mod的方式加载的github上面的包会有报红的问题,但是包本身是可以运行的,这样就是会有一个问题,如果你想要点击去看方法的内容,没办法做到
|
通过go mod的方式加载的github上面的包会有报红的问题,但是包本身是可以运行的,这样就是会有一个问题,如果你想要点击去看方法的内容,没办法做到
|
||||||
@@ -93,4 +114,5 @@
|
|||||||
- 把vendor文件夹删除了
|
- 把vendor文件夹删除了
|
||||||
- 通过 go mod vendor 切换到vendor管理
|
- 通过 go mod vendor 切换到vendor管理
|
||||||
- 在文件中import引用对应的路径
|
- 在文件中import引用对应的路径
|
||||||
- vendor加载对应的包
|
- vendor加载对应的包
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ import (
|
|||||||
//判断num的二进制表示某个位置是否为1
|
//判断num的二进制表示某个位置是否为1
|
||||||
func JudgeOneWithPosition(num int, position int) bool {
|
func JudgeOneWithPosition(num int, position int) bool {
|
||||||
if position < 1 {
|
if position < 1 {
|
||||||
panic(fmt.Sprintf("输入有误:Position不能小于1,当前出入的Position为%d", position))
|
panic(fmt.Sprintf("输入有误:Position不能小于1,"+
|
||||||
|
"当前出入的Position为%d", position))
|
||||||
}
|
}
|
||||||
return num&(1<<uint(position-1)) != 0
|
return num&(1<<uint(position-1)) != 0
|
||||||
}
|
}
|
||||||
@@ -30,16 +31,17 @@ func JudgeIfOdd(num int) bool {
|
|||||||
|
|
||||||
//判断一个数的二进制形式是否只有一个位置为1,这个方法可以用来判断是不是2的n次方
|
//判断一个数的二进制形式是否只有一个位置为1,这个方法可以用来判断是不是2的n次方
|
||||||
func JudgeOnlyOneBitWithOne(num int) bool {
|
func JudgeOnlyOneBitWithOne(num int) bool {
|
||||||
//解析:num & (num -1) 当num为2的N次方的时候, 2N次方 & (2N次方 - 1) ,因为做了最高位的右移(2N次方只有一个1,2N次方-1除了2N次方的那一个1的位置为0,其他都为1)
|
if num == 0 {
|
||||||
//所以&的结果就是 0 ,而0 & 2N次方一定是0,所以如果结果是0,那么一定是2N次方,只有一个位置有1
|
return false
|
||||||
//那么 num & (num -1) 当num不是2的N次方的时候,他的结果原来有1的最高位置,一定为1,所以再和num进行 & 操作的时候,结果也一定是大于0,所以不止一个1
|
}
|
||||||
return num&(num&(num-1)) == 0
|
return num&(num-1) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置num的某一个位置为1,如果原来就是1的话,就不发生变化
|
//设置num的某一个位置为1,如果原来就是1的话,就不发生变化
|
||||||
func SetOneByPosition(num int, position int) int {
|
func SetOneByPosition(num int, position int) int {
|
||||||
if position < 1 {
|
if position < 1 {
|
||||||
panic(fmt.Sprintf("输入有误:Position不能小于1,当前出入的Position为%d", position))
|
panic(fmt.Sprintf("输入有误:Position不能小于1,"+
|
||||||
|
"当前出入的Position为%d", position))
|
||||||
}
|
}
|
||||||
return num | (1 << uint(position-1))
|
return num | (1 << uint(position-1))
|
||||||
}
|
}
|
||||||
@@ -52,7 +54,8 @@ func JudgeWithEqualSymbol(num1 int, num2 int) bool {
|
|||||||
//设置某一个数num的二进制Position位为0
|
//设置某一个数num的二进制Position位为0
|
||||||
func SetZeroBuPosition(num int, position int) int {
|
func SetZeroBuPosition(num int, position int) int {
|
||||||
if position < 1 {
|
if position < 1 {
|
||||||
panic(fmt.Sprintf("输入有误:Position不能小于1,当前出入的Position为%d", position))
|
panic(fmt.Sprintf("输入有误:Position不能小于1,"+
|
||||||
|
"当前出入的Position为%d", position))
|
||||||
}
|
}
|
||||||
return num &^ (1 << uint(position-1))
|
return num &^ (1 << uint(position-1))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,12 +102,9 @@ func TestJudgeIfEven(t *testing.T) {
|
|||||||
|
|
||||||
func TestJudgeOnlyOneBitWithOne(t *testing.T) {
|
func TestJudgeOnlyOneBitWithOne(t *testing.T) {
|
||||||
fmt.Println("判断二进制表示是不是只有一个位为1")
|
fmt.Println("判断二进制表示是不是只有一个位为1")
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(1))
|
for i := 0; i <= 32; i++ {
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(2))
|
fmt.Println(fmt.Sprintf("%d是不是2的n次方,结果为%v", i, JudgeOnlyOneBitWithOne(i)))
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(3))
|
}
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(4))
|
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(56))
|
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(64))
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(-1))
|
fmt.Println(JudgeOnlyOneBitWithOne(-1))
|
||||||
fmt.Println(JudgeOnlyOneBitWithOne(-2))
|
fmt.Println(JudgeOnlyOneBitWithOne(-2))
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ package bitStore
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
bit = 32
|
bit = 32 //作为标识,没有实际作用
|
||||||
realBit = 31
|
realBit = 31 //真实参与计算的每个数字代表的档位数量
|
||||||
)
|
)
|
||||||
|
|
||||||
type BitStore struct {
|
type BitStore struct {
|
||||||
MaxGear int //存储的最大挡位
|
MaxGear int //存储的最大挡位
|
||||||
GearPickList []int
|
GearPickList []int //用来表示档位的数组(每一个数表示【下标 * bit】位的档位存储结果)
|
||||||
}
|
}
|
||||||
|
|
||||||
//初始化方法,gear表示最大的领取档位是多少.(档位刚开始计算,没有值的情况)
|
//初始化方法,gear表示最大的领取档位是多少.(档位刚开始计算,没有值的情况)
|
||||||
@@ -34,6 +34,19 @@ func NewBitStore(gear int, gearPickList []int) *BitStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//返回指定档位长度的领取状态数组
|
||||||
|
func (bitStore *BitStore) FindSpecialGearList(gear int) []bool {
|
||||||
|
bitStore.checkGearRight(gear) //校验传进来的长度是否正确
|
||||||
|
bitStore.getSizeOrInit() //如果数组没有初始化,进行初始化
|
||||||
|
return bitStore.getGearListByGear(gear) //返回指定长度的领取状态数组
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取当前有记录的档位的Map
|
||||||
|
func (bitStore *BitStore) FindGearMap() map[int]bool {
|
||||||
|
listSize := bitStore.getSizeOrInit() //获取当前数组长度,如果数组没有初始化,进行初始化
|
||||||
|
return bitStore.shortListDeal(listSize, listSize) //短数组的处理(没有达到最大大小的数组长度)
|
||||||
|
}
|
||||||
|
|
||||||
//获取所有档位对应的Map
|
//获取所有档位对应的Map
|
||||||
func (bitStore *BitStore) FindAllGearMap() map[int]bool {
|
func (bitStore *BitStore) FindAllGearMap() map[int]bool {
|
||||||
length := bitStore.getGearListLength(bitStore.MaxGear) //获取最大档位的长度
|
length := bitStore.getGearListLength(bitStore.MaxGear) //获取最大档位的长度
|
||||||
@@ -60,10 +73,25 @@ func (bitStore *BitStore) ReceiveByGear(gear int) ([]int, map[int]bool) {
|
|||||||
bitStore.checkIfReceive(gear) //校验是否被领取了
|
bitStore.checkIfReceive(gear) //校验是否被领取了
|
||||||
length := bitStore.dynamicGrowth(gear) //数组进行动态增长
|
length := bitStore.dynamicGrowth(gear) //数组进行动态增长
|
||||||
position := bitStore.getGearPosition(gear, length) //获取档位在数组中的位数位置
|
position := bitStore.getGearPosition(gear, length) //获取档位在数组中的位数位置
|
||||||
bitStore.GearPickList[length-1] = bitStore.GearPickList[length-1] + (1 << uint(position))
|
bitStore.GearPickList[length-1] = bitStore.GearPickList[length-1] | (1 << uint(position))
|
||||||
return bitStore.GearPickList, bitStore.FindAllGearMap()
|
return bitStore.GearPickList, bitStore.FindAllGearMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//设置某一档位为未领取
|
||||||
|
func (bitStore *BitStore) UnReceiveByGear(gear int) ([]int, map[int]bool) {
|
||||||
|
bitStore.checkIfUnReceive(gear) //检验是否被领取
|
||||||
|
length := bitStore.dynamicGrowth(gear) //数组进行动态增长
|
||||||
|
position := bitStore.getGearPosition(gear, length) //获取档位在数组中的位数位置
|
||||||
|
bitStore.GearPickList[length-1] = bitStore.GearPickList[length-1] - (1 << uint(position))
|
||||||
|
return bitStore.GearPickList, bitStore.FindAllGearMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bitStore *BitStore) checkIfUnReceive(gear int) {
|
||||||
|
if !bitStore.IsGearReceive(gear) {
|
||||||
|
panic("当前档位未领取,不可重置")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//判断档位是否正确
|
//判断档位是否正确
|
||||||
func (bitStore *BitStore) checkGearRight(gear int) {
|
func (bitStore *BitStore) checkGearRight(gear int) {
|
||||||
if gear > bitStore.MaxGear {
|
if gear > bitStore.MaxGear {
|
||||||
@@ -73,12 +101,12 @@ func (bitStore *BitStore) checkGearRight(gear int) {
|
|||||||
|
|
||||||
//获取当前档位对应的数组长度(这边的length是从1开始的.)
|
//获取当前档位对应的数组长度(这边的length是从1开始的.)
|
||||||
func (bitStore *BitStore) getGearListLength(gear int) int {
|
func (bitStore *BitStore) getGearListLength(gear int) int {
|
||||||
return ((gear - 1) + (bit - 1)) / (bit - 1)
|
return ((gear - 1) + realBit) / realBit
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取档位所在的二进制位置
|
//获取档位所在的二进制位置
|
||||||
func (bitStore *BitStore) getGearPosition(gear, length int) int {
|
func (bitStore *BitStore) getGearPosition(gear, length int) int {
|
||||||
return (gear - 1) % (bit - 1)
|
return (gear - 1) - realBit*(length-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bitStore *BitStore) getSizeOrInit() int {
|
func (bitStore *BitStore) getSizeOrInit() int {
|
||||||
@@ -91,8 +119,8 @@ func (bitStore *BitStore) getSizeOrInit() int {
|
|||||||
func (bitStore *BitStore) fullListDeal(listSize int, length int) map[int]bool {
|
func (bitStore *BitStore) fullListDeal(listSize int, length int) map[int]bool {
|
||||||
resultMap := make(map[int]bool, 0)
|
resultMap := make(map[int]bool, 0)
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
for j := 0; j < bit-1 && bitStore.MaxGear > i*(bit-1)+j; j++ {
|
for j := 0; j < realBit && bitStore.MaxGear > i*realBit+j; j++ {
|
||||||
resultMap[i*(bit-1)+j+1] = (bitStore.GearPickList[i] & (1 << uint(j))) > 0
|
resultMap[i*realBit+j+1] = (bitStore.GearPickList[i] & (1 << uint(j))) > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resultMap
|
return resultMap
|
||||||
@@ -101,13 +129,14 @@ func (bitStore *BitStore) fullListDeal(listSize int, length int) map[int]bool {
|
|||||||
func (bitStore *BitStore) shortListDeal(listSize, length int) map[int]bool {
|
func (bitStore *BitStore) shortListDeal(listSize, length int) map[int]bool {
|
||||||
resultMap := make(map[int]bool, 0)
|
resultMap := make(map[int]bool, 0)
|
||||||
for i := 0; i < listSize; i++ {
|
for i := 0; i < listSize; i++ {
|
||||||
for j := 0; j < (bit - 1); j++ {
|
for j := 0; j < realBit; j++ {
|
||||||
resultMap[i*(bit-1)+j+1] = (bitStore.GearPickList[i] & (1 << uint(j))) > 0
|
resultMap[i*realBit+j+1] =
|
||||||
|
(bitStore.GearPickList[i] & (1 << uint(j))) > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := listSize; i < length; i++ {
|
for i := listSize; i < length; i++ {
|
||||||
for j := 0; j < (bit-1) && bitStore.MaxGear > i*(bit-1)+j; j++ {
|
for j := 0; j < realBit && bitStore.MaxGear > i*realBit+j; j++ {
|
||||||
resultMap[i*(bit-1)+j+1] = false
|
resultMap[i*realBit+j+1] = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resultMap
|
return resultMap
|
||||||
@@ -131,3 +160,29 @@ func (bitStore *BitStore) checkIfReceive(gear int) {
|
|||||||
panic("当前档位已被领取,不可重复领取")
|
panic("当前档位已被领取,不可重复领取")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bitStore *BitStore) getGearListByGear(gear int) []bool {
|
||||||
|
gearList := make([]bool, 0)
|
||||||
|
listAllGear := len(bitStore.GearPickList) * realBit //当前已领取数组可表示的总档位
|
||||||
|
//如果指定的长度大于gear已有数组长度,需要特殊处理
|
||||||
|
if listAllGear <= gear {
|
||||||
|
for i := 0; i < (listAllGear-1)/realBit+1; i++ {
|
||||||
|
for j := 0; j < realBit && realBit*i+j < gear; j++ {
|
||||||
|
gearList = append(gearList, (bitStore.GearPickList[i]&(1<<uint(j))) > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < gear-listAllGear; i++ {
|
||||||
|
for j := 0; j < realBit && realBit*i+j < gear-listAllGear; j++ {
|
||||||
|
gearList = append(gearList, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gearList
|
||||||
|
}
|
||||||
|
//如果获取的档位比实际记录的档位小
|
||||||
|
for i := 0; i < (gear-1)/realBit+1; i++ {
|
||||||
|
for j := 0; j < realBit && realBit*i+j < gear; j++ {
|
||||||
|
gearList = append(gearList, (bitStore.GearPickList[i]&(1<<uint(j))) > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gearList
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,12 +7,74 @@
|
|||||||
package bitStore
|
package bitStore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Go-Tool/util/sort"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestBitStore(t *testing.T) {
|
||||||
|
fmt.Println("测试2档的情况")
|
||||||
|
testTwo()
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("测试10档的情况")
|
||||||
|
testTen()
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("测试18档的情况")
|
||||||
|
testEighteen()
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("测试33档的情况")
|
||||||
|
testThirtyThree()
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("测试58档的情况")
|
||||||
|
testFiftyEight()
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("测试1000档的情况")
|
||||||
|
testOneThousand(t)
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBitStoreFind(t *testing.T) {
|
||||||
|
bitStore := NewBitStore(120, nil)
|
||||||
|
bitStore.ReceiveByGear(1)
|
||||||
|
bitStore.ReceiveByGear(3)
|
||||||
|
bitStore.ReceiveByGear(5)
|
||||||
|
bitStore.ReceiveByGear(7)
|
||||||
|
bitStore.ReceiveByGear(13)
|
||||||
|
bitStore.ReceiveByGear(10)
|
||||||
|
bitStore.ReceiveByGear(16)
|
||||||
|
bitStore.ReceiveByGear(33)
|
||||||
|
bitStore.ReceiveByGear(35)
|
||||||
|
|
||||||
|
fmt.Println(bitStore.FindGearMap())
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(1))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(1)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(4))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(4)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(2))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(2)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(10))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(10)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(13))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(13)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(14))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(14)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(20))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(20)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(32))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(32)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(63))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(63)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(64))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(64)))
|
||||||
|
fmt.Println(bitStore.FindSpecialGearList(65))
|
||||||
|
fmt.Println(len(bitStore.FindSpecialGearList(65)))
|
||||||
|
}
|
||||||
|
|
||||||
func newStoreMap(bitStore *BitStore) {
|
func newStoreMap(bitStore *BitStore) {
|
||||||
gearMap := bitStore.FindAllGearMap()
|
gearMap := bitStore.FindAllGearMap()
|
||||||
falseList := make([]int, 0)
|
falseList := make([]int, 0)
|
||||||
@@ -34,22 +96,21 @@ func getReceiveResult(bitStore *BitStore) {
|
|||||||
keyList = append(keyList, key)
|
keyList = append(keyList, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.BubbleSort(keyList)
|
|
||||||
fmt.Println("已经领取的档位信息如下")
|
fmt.Println("已经领取的档位信息如下")
|
||||||
for value := range keyList {
|
for value := range keyList {
|
||||||
fmt.Print(fmt.Sprintf("%d,", keyList[value]))
|
fmt.Print(fmt.Sprintf("%d,", keyList[value]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOneThousand(t *testing.T) {
|
func testOneThousand(t *testing.T) {
|
||||||
bitStore := NewBitStore(1000, nil)
|
bitStore := NewBitStore(1000, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
bitStore.ReceiveByGear(1)
|
bitStore.ReceiveByGear(3)
|
||||||
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[0]))
|
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[0]))
|
||||||
fmt.Println(fmt.Sprintf("这个时候领取结果 1应该返回true,结果是:%v", bitStore.IsGearReceive(3)))
|
fmt.Println(fmt.Sprintf("这个时候领取结果 3应该返回true,结果是:%v", bitStore.IsGearReceive(3)))
|
||||||
bitStore.ReceiveByGear(8)
|
bitStore.ReceiveByGear(8)
|
||||||
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[0]))
|
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[0]))
|
||||||
fmt.Println(fmt.Sprintf("这个时候领取结果 8应该返回true,结果是:%v", bitStore.IsGearReceive(8)))
|
fmt.Println(fmt.Sprintf("这个时候领取结果 8应该返回true,结果是:%v", bitStore.IsGearReceive(8)))
|
||||||
@@ -76,10 +137,10 @@ func TestOneThousand(t *testing.T) {
|
|||||||
fmt.Println(fmt.Sprintf("这个时候领取结果 44应该返回true,结果是:%v", bitStore.IsGearReceive(44)))
|
fmt.Println(fmt.Sprintf("这个时候领取结果 44应该返回true,结果是:%v", bitStore.IsGearReceive(44)))
|
||||||
bitStore.ReceiveByGear(48)
|
bitStore.ReceiveByGear(48)
|
||||||
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[1]))
|
fmt.Println(fmt.Sprintf("%b", bitStore.GearPickList[1]))
|
||||||
|
fmt.Println(fmt.Sprintf("这个时候领取结果 48应该返回true,结果是:%v", bitStore.IsGearReceive(48)))
|
||||||
|
|
||||||
fmt.Println(fmt.Sprintf("判断当前数组是否动态增长,当前数组长度为:%d", len(bitStore.GearPickList)))
|
fmt.Println(fmt.Sprintf("判断当前数组是否动态增长,当前数组长度为:%d", len(bitStore.GearPickList)))
|
||||||
|
|
||||||
fmt.Println(fmt.Sprintf("这个时候领取结果 48应该返回true,结果是:%v", bitStore.IsGearReceive(48)))
|
|
||||||
bitStore.ReceiveByGear(123)
|
bitStore.ReceiveByGear(123)
|
||||||
fmt.Println(fmt.Sprintf("这个时候领取结果 123应该返回true,结果是:%v", bitStore.IsGearReceive(123)))
|
fmt.Println(fmt.Sprintf("这个时候领取结果 123应该返回true,结果是:%v", bitStore.IsGearReceive(123)))
|
||||||
|
|
||||||
@@ -100,7 +161,7 @@ func TestOneThousand(t *testing.T) {
|
|||||||
getReceiveResult(bitStore)
|
getReceiveResult(bitStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFiftyEight(t *testing.T) {
|
func testFiftyEight() {
|
||||||
bitStore := NewBitStore(58, nil)
|
bitStore := NewBitStore(58, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
@@ -133,7 +194,7 @@ func TestFiftyEight(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThirtyThree(t *testing.T) {
|
func testThirtyThree() {
|
||||||
bitStore := NewBitStore(33, nil)
|
bitStore := NewBitStore(33, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
@@ -160,7 +221,7 @@ func TestThirtyThree(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEighteen(t *testing.T) {
|
func testEighteen() {
|
||||||
bitStore := NewBitStore(18, nil)
|
bitStore := NewBitStore(18, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
@@ -181,7 +242,7 @@ func TestEighteen(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTen(t *testing.T) {
|
func testTen() {
|
||||||
bitStore := NewBitStore(10, nil)
|
bitStore := NewBitStore(10, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
@@ -200,7 +261,7 @@ func TestTen(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTwo(t *testing.T) {
|
func testTwo() {
|
||||||
bitStore := NewBitStore(2, nil)
|
bitStore := NewBitStore(2, nil)
|
||||||
|
|
||||||
newStoreMap(bitStore) //初始化的校验
|
newStoreMap(bitStore) //初始化的校验
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author : huangzj
|
|
||||||
* @Time : 2020/11/12 14:04
|
|
||||||
* @Description:
|
|
||||||
*/
|
|
||||||
|
|
||||||
package linqUse
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type Book struct {
|
|
||||||
Name string
|
|
||||||
Author string
|
|
||||||
Money float64
|
|
||||||
WordsNum int
|
|
||||||
PublishTime time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeBook() []Book {
|
|
||||||
bookList := make([]Book, 0)
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Effective Java",
|
|
||||||
Author: "Java",
|
|
||||||
Money: 78,
|
|
||||||
WordsNum: 9000,
|
|
||||||
PublishTime: time.Date(2020, 2, 15, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Java语言",
|
|
||||||
Author: "Java",
|
|
||||||
Money: 50,
|
|
||||||
WordsNum: 3000,
|
|
||||||
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Lua语言",
|
|
||||||
Author: "Lua",
|
|
||||||
Money: 75,
|
|
||||||
WordsNum: 45000,
|
|
||||||
PublishTime: time.Date(2020, 1, 10, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "React语言",
|
|
||||||
Author: "React",
|
|
||||||
Money: 99,
|
|
||||||
WordsNum: 14500,
|
|
||||||
PublishTime: time.Date(2020, 7, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Red语言",
|
|
||||||
Author: "Red",
|
|
||||||
Money: 28,
|
|
||||||
WordsNum: 880,
|
|
||||||
PublishTime: time.Date(2019, 4, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "JavaScript语言",
|
|
||||||
Author: "JavaScript",
|
|
||||||
Money: 81,
|
|
||||||
WordsNum: 3776,
|
|
||||||
PublishTime: time.Date(2019, 5, 17, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
return bookList
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeBook1() []Book {
|
|
||||||
bookList := make([]Book, 0)
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Effective Java",
|
|
||||||
Author: "Java",
|
|
||||||
Money: 78,
|
|
||||||
WordsNum: 9000,
|
|
||||||
PublishTime: time.Date(2020, 2, 15, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言(第二版)",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 50,
|
|
||||||
WordsNum: 3000,
|
|
||||||
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
return bookList
|
|
||||||
}
|
|
||||||
func MakeBook2() []Book {
|
|
||||||
bookList := make([]Book, 0)
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
return bookList
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeBook3() []Book {
|
|
||||||
bookList := make([]Book, 0)
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList = append(bookList, Book{
|
|
||||||
Name: "Go语言(第三版)",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 50,
|
|
||||||
WordsNum: 3000,
|
|
||||||
PublishTime: time.Date(2020, 2, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
return bookList
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author : huangzj
|
|
||||||
* @Time : 2020/11/24 16:17
|
|
||||||
* @Description:
|
|
||||||
*/
|
|
||||||
|
|
||||||
package linqUse
|
|
||||||
|
|
||||||
type Person struct {
|
|
||||||
Name string //拥有者的名字
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pet struct {
|
|
||||||
Name string //动物的名字
|
|
||||||
OwnerName string //拥有者的名字
|
|
||||||
}
|
|
||||||
|
|
||||||
type Man struct {
|
|
||||||
Name string //拥有者的名字
|
|
||||||
Pets []Pets //宠物们
|
|
||||||
}
|
|
||||||
|
|
||||||
type Pets struct {
|
|
||||||
Name string //动物的名字
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeInnerData() []Man {
|
|
||||||
man := make([]Man, 0)
|
|
||||||
man = append(man, Man{
|
|
||||||
Name: "康康",
|
|
||||||
Pets: []Pets{{Name: "康康的狗"}, {Name: "康康的猫"}},
|
|
||||||
})
|
|
||||||
man = append(man, Man{
|
|
||||||
Name: "老施",
|
|
||||||
Pets: []Pets{{Name: "老施的🐟"}, {Name: "老施的鸟"}},
|
|
||||||
})
|
|
||||||
man = append(man, Man{
|
|
||||||
Name: "小明",
|
|
||||||
Pets: []Pets{{Name: "小明的🐖"}, {Name: "小明的狗"}},
|
|
||||||
})
|
|
||||||
|
|
||||||
return man
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeJoinData() ([]Person, []Pet) {
|
|
||||||
kangkang := Person{Name: "爱吃合合乐的康康"}
|
|
||||||
laoshi := Person{Name: "老施"}
|
|
||||||
xiaoming := Person{Name: "不要催-小明"}
|
|
||||||
expect := Person{Name: "我是没有宠物的人"}
|
|
||||||
|
|
||||||
dog := Pet{Name: "康康的狗", OwnerName: kangkang.Name}
|
|
||||||
cat := Pet{Name: "康康的猫", OwnerName: kangkang.Name}
|
|
||||||
fish := Pet{Name: "老施的🐟", OwnerName: laoshi.Name}
|
|
||||||
pig := Pet{Name: "小明的🐖", OwnerName: xiaoming.Name}
|
|
||||||
|
|
||||||
return []Person{kangkang, laoshi, xiaoming, expect}, []Pet{dog, cat, fish, pig}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author : huangzj
|
|
||||||
* @Time : 2020/11/12 14:43
|
|
||||||
* @Description:测试方法集合
|
|
||||||
*/
|
|
||||||
|
|
||||||
package linqUse
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
//书籍发布时间是否早于--.--.--
|
|
||||||
var PublishTimeBeforeFunc = func(thisBook interface{}) bool {
|
|
||||||
if thisBook.(Book).PublishTime.Before(time.Date(2019, 1, 1, 0, 0, 0, 0, time.Local)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//书籍发布时间是否晚于--.--.--
|
|
||||||
var PublishTimeAfterFunc = func(thisBook interface{}) bool {
|
|
||||||
if thisBook.(Book).PublishTime.After(time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//书籍发布时间是否晚于--.--.--
|
|
||||||
var PublishTimeAfterFunc2 = func(thisBook interface{}) bool {
|
|
||||||
if thisBook.(Book).PublishTime.After(time.Date(2021, 1, 1, 0, 0, 0, 0, time.Local)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//自定义聚合操作方法
|
|
||||||
var AggregateFunc = func(first interface{}, second interface{}) interface{} {
|
|
||||||
if first.(Book).PublishTime.Before(second.(Book).PublishTime) {
|
|
||||||
return first
|
|
||||||
}
|
|
||||||
return second
|
|
||||||
}
|
|
||||||
@@ -1,531 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author : huangzj
|
|
||||||
* @Time : 2020/11/12 10:52
|
|
||||||
* @Description:这边是linq包的使用操作,为之后的使用做一些示例
|
|
||||||
* 包引用命令: go get github.com/ahmetb/go-linq
|
|
||||||
* 示例参考地址:https://godoc.org/github.com/ahmetb/go-linq#
|
|
||||||
* 在Idea中对应方法名上使用 Shift+F1 组合键操作可以直接跳转到方法对应的地址
|
|
||||||
*/
|
|
||||||
|
|
||||||
package linqUse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"Go-Tool/util/timed"
|
|
||||||
"fmt"
|
|
||||||
"github.com/ahmetb/go-linq"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
|
||||||
|
|
||||||
Aggregate() //自定义聚合操作
|
|
||||||
|
|
||||||
All() //判断数组的所有元素是否都满足条件
|
|
||||||
|
|
||||||
Where() //根据条件查询对应的元素
|
|
||||||
|
|
||||||
AnyWith() //判断数组是否有任意个元素满足条件
|
|
||||||
|
|
||||||
Calculate() //这个方法只能计算数值类型
|
|
||||||
|
|
||||||
Combine() //组合两个数组的两种方式
|
|
||||||
|
|
||||||
Contains() //包含
|
|
||||||
|
|
||||||
FirstAndLast() //第一个和最后一个
|
|
||||||
|
|
||||||
Distinct() //返回数组中唯一的元素
|
|
||||||
|
|
||||||
Except() //返回第一个序列没有出现在第二个序列中的成员
|
|
||||||
|
|
||||||
GroupBy() //按照对应规则进行分组
|
|
||||||
|
|
||||||
Intersect() //产生两个数组的交集
|
|
||||||
|
|
||||||
OrderBy() //排序
|
|
||||||
|
|
||||||
Skip() //略过指定条件的元素
|
|
||||||
|
|
||||||
Count() //计算数组总长度
|
|
||||||
|
|
||||||
Result() //对结果集进行操作
|
|
||||||
|
|
||||||
Take() //获取对应数量的元素,一般多用在排序后前几个的元素
|
|
||||||
|
|
||||||
Select() //筛选结构体中对应的元素
|
|
||||||
|
|
||||||
SelectMany() //对多维数组进行合并或者其他处理 对结构体中的数组进行处理(与结构体结合操作)
|
|
||||||
|
|
||||||
Join() //对两个有关联的数据进行处理
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Where() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
query.WhereT(func(book Book) bool {
|
|
||||||
return book.Money > float64(70)
|
|
||||||
}).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Take() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
query.OrderByDescendingT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).Take(3).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
//超出对应数量的元素会不会报错(输出所有的元素)
|
|
||||||
query.OrderByDescendingT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).Take(100).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
//负数会发生什么情况(直接返回,不做操作)
|
|
||||||
query.OrderByDescendingT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).Take(-2).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
|
|
||||||
})
|
|
||||||
|
|
||||||
//TakeWhile系列的方法,虽然能够根据条件进行查询,但是有一个弊端就是一旦查询到的结果和条件不符合则直接返回,也就是说后面满足条件的元素不会再被做筛选
|
|
||||||
//那么比如这边的这个大于的操作,就需要对整个数组进行排序之后然后进行筛选,如果不希望排序,则用原生的for循环可能会更好
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
query.TakeWhileT(func(book Book) bool {
|
|
||||||
return book.Money > float64(70)
|
|
||||||
}).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", book.Author, book.Name))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Result() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
|
|
||||||
bookMap := make(map[string]string, 0)
|
|
||||||
query.SelectT(func(book Book) linq.KeyValue {
|
|
||||||
return linq.KeyValue{
|
|
||||||
Key: book.Author,
|
|
||||||
Value: book.Name,
|
|
||||||
}
|
|
||||||
}).ToMap(&bookMap)
|
|
||||||
|
|
||||||
for key, value := range bookMap {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
//如果key相同的话,前面的元素会被覆盖掉(只会保留最后一个)
|
|
||||||
bookList1 := MakeBook1()
|
|
||||||
query1 := linq.From(bookList1)
|
|
||||||
bookMap1 := make(map[string]string, 0)
|
|
||||||
query1.SelectT(func(book Book) linq.KeyValue {
|
|
||||||
return linq.KeyValue{
|
|
||||||
Key: book.Author,
|
|
||||||
Value: book.Name,
|
|
||||||
}
|
|
||||||
}).ToMap(&bookMap1)
|
|
||||||
|
|
||||||
for key, value := range bookMap1 {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
bookList2 := MakeBook()
|
|
||||||
query2 := linq.From(bookList2)
|
|
||||||
|
|
||||||
bookMap2 := make(map[string]Book, 0)
|
|
||||||
query2.ToMapByT(&bookMap2,
|
|
||||||
//这个方法决定key的字段是什么
|
|
||||||
func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}, //这个方法决定value的字段是什么
|
|
||||||
func(book Book) Book {
|
|
||||||
return book
|
|
||||||
})
|
|
||||||
|
|
||||||
for key, value := range bookMap2 {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", key, value.Name))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
bookListResult := make([]Book, 0)
|
|
||||||
linq.From(MakeBook()).OrderByDescendingT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).ToSlice(&bookListResult)
|
|
||||||
for _, value := range bookListResult {
|
|
||||||
fmt.Println(fmt.Sprintf("作者%v,写了一本书叫做%v", value.Author, value.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Count() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
fmt.Println(fmt.Sprintf("数组中发布时间早于2019-1-1的书有%d本", query.CountWithT(PublishTimeBeforeFunc)))
|
|
||||||
fmt.Println(fmt.Sprintf("数组中发布时间晚于2018-1-1的书有%d本", query.CountWithT(PublishTimeAfterFunc)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Skip() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
|
|
||||||
fmt.Println(fmt.Sprintf("跳过三个元素,返回的数组中包含%d个元素", len(query.Skip(3).Results())))
|
|
||||||
fmt.Println(fmt.Sprintf("跳过发布时间在2018.1.1之后的元素,返回的数组中包含%d个元素", query.SkipWhile(PublishTimeAfterFunc).Count()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func SelectMany() {
|
|
||||||
input := [][]int{{1, 2, 3}, {4, 5, 6, 7}}
|
|
||||||
|
|
||||||
//二位数组进行合并
|
|
||||||
linq.From(input).SelectManyT(
|
|
||||||
func(i []int) linq.Query {
|
|
||||||
return linq.From(i)
|
|
||||||
},
|
|
||||||
).ForEachT(func(num int) {
|
|
||||||
fmt.Println(num)
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
//三维数组进行合并
|
|
||||||
input1 := [][][]int{{{1, 2, 3}}, {{4, 5, 6, 7}, {8, 9, 10}}}
|
|
||||||
linq.From(input1).SelectManyT(
|
|
||||||
func(i [][]int) linq.Query {
|
|
||||||
return linq.From(i)
|
|
||||||
},
|
|
||||||
).SelectManyT(
|
|
||||||
func(i []int) linq.Query {
|
|
||||||
return linq.From(i)
|
|
||||||
},
|
|
||||||
).ForEachT(func(num int) {
|
|
||||||
fmt.Print(num)
|
|
||||||
fmt.Print(" ")
|
|
||||||
})
|
|
||||||
|
|
||||||
//SelectMany的主要作用是,结构体中包含数组元素,可以把数组元素取出来和结构体做相应的操作
|
|
||||||
//如果是结构体中有多个数组的操作,可以把对应的多个数组放到一个新定义的结构体数组中
|
|
||||||
fmt.Println()
|
|
||||||
men := MakeInnerData()
|
|
||||||
linq.From(men).
|
|
||||||
//第一个方法筛选出结构体对应的数组
|
|
||||||
SelectManyByT(func(man Man) linq.Query {
|
|
||||||
return linq.From(man.Pets)
|
|
||||||
},
|
|
||||||
//第二个方法这边可以拿到数组中元素对应的结构体的数据.
|
|
||||||
func(pet Pets, man Man) map[string]Pets {
|
|
||||||
return map[string]Pets{
|
|
||||||
man.Name: pet,
|
|
||||||
}
|
|
||||||
}).ForEachT(func(petWithMan map[string]Pets) {
|
|
||||||
for key, value := range petWithMan {
|
|
||||||
fmt.Println(fmt.Sprintf("%v拥有一只宠物,它的名字叫做%v", key, value.Name))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func Select() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
|
|
||||||
//筛选出结构体对应的元素
|
|
||||||
query.SelectT(func(book Book) string {
|
|
||||||
return book.Name
|
|
||||||
}).ForEachT(func(bookName string) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v", bookName))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
//根据下标进行返回,如果是跟下标有关的,则可以通过这个方法进行组合然后返回.
|
|
||||||
query.SelectIndexedT(func(index int, book Book) []string {
|
|
||||||
return []string{strconv.Itoa(index + 1), book.Name}
|
|
||||||
}).ForEachT(func(book []string) {
|
|
||||||
fmt.Println(fmt.Sprintf("第%v本书,书名%v", book[0], book[1]))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//OrderBy可以按照对应的规则进行排序,可以实现多重排序,需要注意的就是OrderBy是从到达,orderByDescending是从大到小
|
|
||||||
func OrderBy() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
query = query.OrderByDescendingT(func(book Book) string {
|
|
||||||
return book.Name
|
|
||||||
}).ThenByDescendingT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).ThenByDescendingT(func(book Book) float64 {
|
|
||||||
return book.Money
|
|
||||||
}).Query
|
|
||||||
|
|
||||||
query.ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
//reverse: 把结果逆序
|
|
||||||
query.Reverse().ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Join() {
|
|
||||||
//任务和动物有关联,直接找到对应的关系,没有对应关系的数据不会处理,正常情况下应该用更单一的数据来做关联
|
|
||||||
persons, pets := MakeJoinData()
|
|
||||||
query1 := linq.From(persons)
|
|
||||||
query2 := linq.From(pets)
|
|
||||||
query1.JoinT(query2,
|
|
||||||
func(person Person) string {
|
|
||||||
return person.Name
|
|
||||||
},
|
|
||||||
func(pet Pet) string {
|
|
||||||
return pet.OwnerName
|
|
||||||
},
|
|
||||||
func(person Person, pet Pet) map[string]Pet {
|
|
||||||
petMap := make(map[string]Pet)
|
|
||||||
petMap[person.Name] = pet
|
|
||||||
return petMap
|
|
||||||
},
|
|
||||||
).ForEachT(func(petMap map[string]Pet) {
|
|
||||||
for key, value := range petMap {
|
|
||||||
fmt.Println(fmt.Sprintf("%v拥有一只宠物,它的名字叫做:%v", key, value.Name))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Intersect() {
|
|
||||||
bookList1 := MakeBook1()
|
|
||||||
query1 := linq.From(bookList1)
|
|
||||||
bookList2 := MakeBook2()
|
|
||||||
query2 := linq.From(bookList2)
|
|
||||||
|
|
||||||
fmt.Println("输出对应的书籍元素,按照结构体判断交集")
|
|
||||||
query3 := query1.Intersect(query2)
|
|
||||||
query3.ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("输出对应的书籍元素,按照元素判断交集")
|
|
||||||
query3 = query1.IntersectByT(query2, func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
})
|
|
||||||
query3.ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
|
|
||||||
//这边计算是按照结构体的一个元素进行比较。事实证明无论是否按照结构体的元素筛选,返回的都是完全相同的元素
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("输出对应的书籍元素,按照元素判断交集2")
|
|
||||||
bookList1 = MakeBook1()
|
|
||||||
query1 = linq.From(bookList1)
|
|
||||||
bookList3 := MakeBook3()
|
|
||||||
query2 = linq.From(bookList3)
|
|
||||||
query3 = query2.IntersectByT(query1, func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
})
|
|
||||||
query3.ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("判断是否会不重复的处理")
|
|
||||||
query1 = linq.From([]int{1, 2, 3, 4, 5, 3})
|
|
||||||
query2 = linq.From([]int{1, 3, 3, 78, 99, 0, 111})
|
|
||||||
query3 = query2.IntersectByT(query1, func(i int) int {
|
|
||||||
return i
|
|
||||||
})
|
|
||||||
fmt.Println(query3.Results())
|
|
||||||
}
|
|
||||||
|
|
||||||
func GroupBy() {
|
|
||||||
bookList1 := MakeBook1()
|
|
||||||
query := linq.From(bookList1)
|
|
||||||
|
|
||||||
fmt.Println("输出对应书名和作者")
|
|
||||||
//第一个func是分组的依据,第二个func是分组后返回的元素.
|
|
||||||
query = query.GroupByT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}, func(book Book) Book {
|
|
||||||
return book
|
|
||||||
})
|
|
||||||
|
|
||||||
query.ForEachT(func(bookGroup linq.Group) {
|
|
||||||
fmt.Println(fmt.Sprintf("作者是%v", bookGroup.Key))
|
|
||||||
for _, item := range bookGroup.Group {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", item.(Book).Name, item.(Book).Author))
|
|
||||||
fmt.Println()
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("输出对应书名")
|
|
||||||
|
|
||||||
bookList1 = MakeBook1()
|
|
||||||
query = linq.From(bookList1)
|
|
||||||
var nameGroups []linq.Group
|
|
||||||
query.GroupByT(
|
|
||||||
func(book Book) string { return book.Author },
|
|
||||||
func(book Book) string { return book.Name },
|
|
||||||
).ToSlice(&nameGroups)
|
|
||||||
|
|
||||||
for _, item := range nameGroups {
|
|
||||||
fmt.Println(fmt.Sprintf("作者是%v", item.Key))
|
|
||||||
for _, row := range item.Group {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v", row))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Except() {
|
|
||||||
bookList1 := MakeBook1()
|
|
||||||
query1 := linq.From(bookList1)
|
|
||||||
bookList2 := MakeBook2()
|
|
||||||
query2 := linq.From(bookList2)
|
|
||||||
|
|
||||||
fmt.Println("输出对应书名和作者")
|
|
||||||
//判断结构结构体本身是否相等
|
|
||||||
query1.Except(query2).
|
|
||||||
ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("输出对应书名和作者")
|
|
||||||
//判断结构体的某个字段是否出现
|
|
||||||
query1.ExceptByT(query2, func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Distinct() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
query = query.Append(Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
bookList1 := make([]Book, 0)
|
|
||||||
query.ToSlice(&bookList1)
|
|
||||||
fmt.Println(fmt.Sprintf("筛选之前query中总共有%d个数据", query.Count()))
|
|
||||||
//这边的distinct如果是结构体,则判断的是结构体的所有值,如果是指针则判断的是指针地址.
|
|
||||||
query = query.Distinct()
|
|
||||||
fmt.Println(fmt.Sprintf("筛选之后query中总共有%d个数据", query.Count()))
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("输出对应书名和作者")
|
|
||||||
query = query.Append(Book{
|
|
||||||
Name: "Go语言(第二版)",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})
|
|
||||||
//根据对应的规则来判断是否相同 -- 如果对应的字段一样,只会保留第一个找到的,后面的会被清除掉
|
|
||||||
query.DistinctByT(func(book Book) string {
|
|
||||||
return book.Author
|
|
||||||
}).ForEachT(func(book Book) {
|
|
||||||
fmt.Println(fmt.Sprintf("书名%v,作者%v", book.Name, book.Author))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Combine() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
query1 := query.Concat(query) //不会排除重复项
|
|
||||||
query2 := query.Union(query) //会排除重复项
|
|
||||||
fmt.Println(fmt.Sprintf("不会排除重复项的方法返回的元素个数是%d", len(query1.Results())))
|
|
||||||
fmt.Println(fmt.Sprintf("会排除重复项的方法返回的元素个数是%d", len(query2.Results())))
|
|
||||||
query1 = query1.Append(Book{Name: "Last One"}) //加在原来的Query的最后面
|
|
||||||
query2 = query2.Prepend(Book{Name: "First One"}) //加在原来的Query的第一个
|
|
||||||
fmt.Println(fmt.Sprintf("最后一个元素是%v", query1.Last()))
|
|
||||||
fmt.Println(fmt.Sprintf("第一个元素是%v", query2.First()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func FirstAndLast() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
fmt.Println(fmt.Sprintf("数组第一本书书名叫:%s", query.First().(Book).Name))
|
|
||||||
fmt.Println(fmt.Sprintf("数组第一本书发布时间在2018年1月1号之后的书书名叫:%s", query.FirstWith(PublishTimeAfterFunc).(Book).Name))
|
|
||||||
|
|
||||||
fmt.Println(fmt.Sprintf("数组最后一本书书名叫:%s", query.Last().(Book).Name))
|
|
||||||
fmt.Println(fmt.Sprintf("数组最后一本书发布时间在2018年1月1号之后的书书名叫:%s", query.LastWith(PublishTimeAfterFunc).(Book).Name))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Contains() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
//这边需要注意是的是如果要判断两个元素是否相等,在go里面不能使用元素的地址
|
|
||||||
// 所以这边加到query里面的必须不能是元素的地址,否则没办法比较结构体本身,而是比较结构体的地址
|
|
||||||
fmt.Println(fmt.Sprintf("判断当前数组是否包含相同的元素,判断的是所有的值,而不是地址,结果是%v", query.Contains(Book{
|
|
||||||
Name: "Go语言",
|
|
||||||
Author: "Go",
|
|
||||||
Money: 100,
|
|
||||||
WordsNum: 1000,
|
|
||||||
PublishTime: time.Date(2020, 1, 1, 10, 0, 0, 0, time.Local),
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Calculate() {
|
|
||||||
query := linq.From([]int{1, 2, 3, 4, 5, 6, 7, 8, 9})
|
|
||||||
fmt.Println(fmt.Sprintf("平均值为:%f", query.Average()))
|
|
||||||
fmt.Println(fmt.Sprintf("最大的值为%d", query.Max()))
|
|
||||||
fmt.Println(fmt.Sprintf("最小的值为%d", query.Min()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func AnyWith() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
result := query.AnyWith(PublishTimeBeforeFunc) //判断是否有任意个元素满足条件
|
|
||||||
fmt.Println(fmt.Sprintf("是否有任意书的发表时间早于2020年1月1号,答案是%v", result))
|
|
||||||
|
|
||||||
result = query.AnyWith(PublishTimeAfterFunc2) //判断是否有任意个元素满足条件
|
|
||||||
fmt.Println(fmt.Sprintf("是否有任意书的发表时间晚于2021年1月1号,答案是%v", result))
|
|
||||||
}
|
|
||||||
|
|
||||||
func All() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
result := query.All(PublishTimeBeforeFunc)
|
|
||||||
fmt.Println(fmt.Sprintf("是否所有的书的发表时间都早于2020年1月1号,答案是%v", result))
|
|
||||||
|
|
||||||
result = query.All(PublishTimeAfterFunc)
|
|
||||||
fmt.Println(fmt.Sprintf("是否所有的书的发表时间都晚于2018年1月1号,答案是%v", result))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Aggregate() {
|
|
||||||
bookList := MakeBook()
|
|
||||||
query := linq.From(bookList)
|
|
||||||
// 这边的聚合操作其实就是【自定义对应的比较方法】。
|
|
||||||
// 根据注释,第一次拿到的是数组的第一个元素,然后跟第二个元素进行比较,如果第二个元素符合条件则【替换第一个元素】,否则当前聚合操作还是持有第一个元素。
|
|
||||||
// 以此类推后面的元素
|
|
||||||
result := query.Aggregate(AggregateFunc).(Book)
|
|
||||||
fmt.Println(fmt.Sprintf("聚合操作查询出的结果是【%s】这本书,它的发布时间最早为:%v", result.Name, timed.GetTimeDefaultFormatString(result.PublishTime.Unix())))
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/13 21:58
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package palindrome
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
//返回字符串中最大回文的数量和回文字符串
|
||||||
|
func Manacher(allString string) (int, string) {
|
||||||
|
maxMid := 0 //当前最大回文串中部下标
|
||||||
|
radiusPos := 0 //最大回文半径对应的右边的下标位置
|
||||||
|
result := generateString(allString)
|
||||||
|
point := make([]int, len(result)) //以j为中心的最长回文半径
|
||||||
|
maxLen := -1
|
||||||
|
var palindrome string
|
||||||
|
|
||||||
|
for i := 1; i < len(result); i++ {
|
||||||
|
j := 2*maxMid - i //与i下标对称的左边的下标
|
||||||
|
if i >= radiusPos {
|
||||||
|
point[i] = 1
|
||||||
|
} else if radiusPos-i > point[j] {
|
||||||
|
point[i] = point[j]
|
||||||
|
} else {
|
||||||
|
// point[j] >= radiusPos-i
|
||||||
|
point[i] = radiusPos - i
|
||||||
|
}
|
||||||
|
//从后面的位置继续开始找对应的字符
|
||||||
|
for (i-point[i] >= 0 && i+point[i] < len(result)) && result[i+point[i]] == result[i-point[i]] {
|
||||||
|
point[i]++
|
||||||
|
}
|
||||||
|
//更新最长回文串信息
|
||||||
|
if i+point[i] > radiusPos {
|
||||||
|
maxMid = i
|
||||||
|
radiusPos = i + point[i]
|
||||||
|
}
|
||||||
|
if maxLen < point[i]-1 && point[i]-1 > 1 {
|
||||||
|
maxLen = point[i] - 1
|
||||||
|
palindrome = allString[maxMid/2-maxLen/2 : radiusPos/2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxLen, palindrome
|
||||||
|
}
|
||||||
|
|
||||||
|
//把字符串转换成特殊的字符串
|
||||||
|
func generateString(allString string) string {
|
||||||
|
var result string
|
||||||
|
for i := range allString {
|
||||||
|
result = fmt.Sprintf("%s%s%c", result, "#", allString[i])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%s", result, "#")
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/13 21:58
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package palindrome
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateString(t *testing.T) {
|
||||||
|
fmt.Println(generateString("abcdef"))
|
||||||
|
fmt.Println(generateString("abc2342def"))
|
||||||
|
fmt.Println(generateString("abcdef3213"))
|
||||||
|
fmt.Println(generateString("abcderewrewr312f"))
|
||||||
|
fmt.Println(generateString("312312abcdef321e"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPalindrome(t *testing.T) {
|
||||||
|
fmt.Println(Manacher("abcabccbacba"))
|
||||||
|
fmt.Println(Manacher("mabcabccbacbammm"))
|
||||||
|
fmt.Println(Manacher("habcabccbacbammm"))
|
||||||
|
fmt.Println(Manacher("hmmmabcabccbacbammm"))
|
||||||
|
fmt.Println(Manacher("abcdefghij"))
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/23 20:52
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rand
|
||||||
|
|
||||||
|
type AwardWeight struct {
|
||||||
|
Award interface{} //奖励数据
|
||||||
|
Weight int //权重
|
||||||
|
}
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : huangzj
|
* @Author : huangzj
|
||||||
* @Time : 2020/6/29 10:48
|
* @Time : 2020/6/29 10:48
|
||||||
* @Description:这边的随机获取没有加锁,对于一些需要加锁的场景可以在外面再包装一层
|
* @Description:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package rand
|
package rand
|
||||||
@@ -47,7 +47,7 @@ func GetRandIntNoRepeat(count, min, max int) []int {
|
|||||||
return randAttr
|
return randAttr
|
||||||
}
|
}
|
||||||
|
|
||||||
//从一个数组中获取到X个不重复随机数
|
//从一个数组中获取到X个不重复下标的随机数
|
||||||
func GetDiffNum(data []int, count int) []int {
|
func GetDiffNum(data []int, count int) []int {
|
||||||
if count > len(data) {
|
if count > len(data) {
|
||||||
panic("获取随机数数量有误")
|
panic("获取随机数数量有误")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : huangzj
|
* @Author : huangzj
|
||||||
* @Time : 2020/6/29 10:23
|
* @Time : 2020/6/29 10:23
|
||||||
* @Description:这边的随机获取没有加锁,对于一些需要加锁的场景可以在外面再包装一层
|
* @Description:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package rand
|
package rand
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/23 20:50
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rand
|
||||||
|
|
||||||
|
func GetAwardWeightByWeight(awardWeight []*AwardWeight) *AwardWeight {
|
||||||
|
//求总权重
|
||||||
|
weight := 0
|
||||||
|
for _, award := range awardWeight {
|
||||||
|
weight += award.Weight
|
||||||
|
}
|
||||||
|
randNum := GetRandInt(1, weight)
|
||||||
|
sum := 0
|
||||||
|
for _, award := range awardWeight {
|
||||||
|
sum += award.Weight
|
||||||
|
if sum >= randNum {
|
||||||
|
return award
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据权重不放回的抽取,出参是:抽到的道具、剩余没有抽的道具
|
||||||
|
func GetByWeightWithLeftAward(awardWeight []*AwardWeight) (*AwardWeight, []*AwardWeight) {
|
||||||
|
weight := 0
|
||||||
|
leftAwards := make([]*AwardWeight, 0)
|
||||||
|
for _, award := range awardWeight {
|
||||||
|
weight += award.Weight
|
||||||
|
}
|
||||||
|
randNum := GetRandInt(1, weight)
|
||||||
|
sum := 0
|
||||||
|
for index, award := range awardWeight {
|
||||||
|
sum += award.Weight
|
||||||
|
if sum >= randNum {
|
||||||
|
//如果获取到奖励则将当前获取的奖励扣除
|
||||||
|
leftAwards = append(awardWeight[0:index], awardWeight[index+1:]...)
|
||||||
|
return award, leftAwards
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, leftAwards
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据权重不放回的抽取X个元素,直接返回这些元素
|
||||||
|
// 入参:奖池、抽取数量,出参:获得的所有道具,剩余的其他道具
|
||||||
|
func GetSomeAwardsFromPool(srcAwardPool []*AwardWeight, count int) ([]*AwardWeight, []*AwardWeight) {
|
||||||
|
if count > len(srcAwardPool) {
|
||||||
|
panic("抽取数量不对")
|
||||||
|
}
|
||||||
|
var finalAwardList []*AwardWeight
|
||||||
|
var award *AwardWeight
|
||||||
|
var leftAward = make([]*AwardWeight, len(srcAwardPool))
|
||||||
|
copy(leftAward, srcAwardPool)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
award, leftAward = GetByWeightWithLeftAward(leftAward)
|
||||||
|
finalAwardList = append(finalAwardList, award)
|
||||||
|
}
|
||||||
|
return finalAwardList, leftAward
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/23 22:08
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRandByAwardWeight(t *testing.T) {
|
||||||
|
awardList := make([]*AwardWeight, 0)
|
||||||
|
awardList = append(awardList, &AwardWeight{
|
||||||
|
Award: []int{1, 2},
|
||||||
|
Weight: 10,
|
||||||
|
})
|
||||||
|
awardList = append(awardList, &AwardWeight{
|
||||||
|
Award: []int{2, 2},
|
||||||
|
Weight: 20,
|
||||||
|
})
|
||||||
|
awardList = append(awardList, &AwardWeight{
|
||||||
|
Award: []int{3, 2},
|
||||||
|
Weight: 30,
|
||||||
|
})
|
||||||
|
|
||||||
|
award := GetAwardWeightByWeight(awardList)
|
||||||
|
fmt.Println(award.Award)
|
||||||
|
|
||||||
|
award1, list3 := GetByWeightWithLeftAward(awardList)
|
||||||
|
fmt.Println(award1.Award)
|
||||||
|
for _, award := range list3 {
|
||||||
|
fmt.Println(award.Award)
|
||||||
|
}
|
||||||
|
|
||||||
|
list4, left := GetSomeAwardsFromPool(awardList, 2)
|
||||||
|
for _, award := range list4 {
|
||||||
|
fmt.Println(award.Award)
|
||||||
|
}
|
||||||
|
for _, award := range left {
|
||||||
|
fmt.Println(award.Award)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ func LomutoPartition(list []int, start int, end int) int {
|
|||||||
if list[i] < compareValue {
|
if list[i] < compareValue {
|
||||||
moveSubscript++
|
moveSubscript++
|
||||||
charge++
|
charge++
|
||||||
list[moveSubscript], list[i] = list[i], list[moveSubscript]
|
list[moveSubscript], list[i] = list[i], list[moveSubscript] //交换元素
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
charge++
|
charge++
|
||||||
|
|||||||
@@ -13,17 +13,26 @@ import (
|
|||||||
|
|
||||||
func TestPartition(t *testing.T) {
|
func TestPartition(t *testing.T) {
|
||||||
list := []int{99, 1, 2, 3, 4, 100, 200, 90, 5}
|
list := []int{99, 1, 2, 3, 4, 100, 200, 90, 5}
|
||||||
s := LomutoPartition(list, 0, 9-1)
|
|
||||||
fmt.Println(fmt.Sprintf("当前第一个元素应该存在位置为:%d", s))
|
for i := 1; i <= len(list); i++ {
|
||||||
for _, r := range list {
|
s := LomutoPartition(list, 0, len(list)-1)
|
||||||
fmt.Print(r, " ")
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前第一个元素应该存在位置为:%d", s))
|
||||||
|
for _, r := range list {
|
||||||
|
fmt.Print(r, " ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s = LomutoPartition(list, 0, 9-1)
|
fmt.Println()
|
||||||
fmt.Println(fmt.Sprintf("当前第一个元素应该存在位置为:%d", s))
|
for i := 1; i <= len(list); i++ {
|
||||||
for _, r := range list {
|
num, _, _ := LomutoQuiteSelect(list, i)
|
||||||
fmt.Print(r, " ")
|
fmt.Println(fmt.Sprintf("第%d个位置的数是:%d", i, num))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
fmt.Println(list[i])
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func doc() string {
|
func doc() string {
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ func QuickSort(list []int, start, end int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QuickSortByte(list []byte, start, end int) {
|
||||||
|
if start < end {
|
||||||
|
position := hoarePartition1(list, start, end)
|
||||||
|
QuickSortByte(list, start, position) //注意这边结束的下表是position,而不是position + 1
|
||||||
|
QuickSortByte(list, position+1, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//通过lomuto划分来实现快速排序
|
//通过lomuto划分来实现快速排序
|
||||||
func QuickSort1(list []int, start, end int) {
|
func QuickSort1(list []int, start, end int) {
|
||||||
if start < end {
|
if start < end {
|
||||||
@@ -26,6 +34,25 @@ func QuickSort1(list []int, start, end int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hoarePartition1(list []byte, start int, end int) int {
|
||||||
|
value := list[start] //比较的元素
|
||||||
|
s := start
|
||||||
|
e := end
|
||||||
|
for s < e {
|
||||||
|
//找到数组终止前,比目标数(value)大的数字
|
||||||
|
for ; s < end && list[s] < value; s++ {
|
||||||
|
}
|
||||||
|
//找到数组结束前,比目标数(value)小的数字
|
||||||
|
for ; e > start && list[e] >= value; e-- {
|
||||||
|
}
|
||||||
|
if s < e {
|
||||||
|
list[s], list[e] = list[e], list[s]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list[start], list[e] = list[e], list[start]
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func hoarePartition(list []int, start int, end int) int {
|
func hoarePartition(list []int, start int, end int) int {
|
||||||
value := list[start] //比较的元素
|
value := list[start] //比较的元素
|
||||||
s := start
|
s := start
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
## 需求
|
||||||
|
这里的实际需求是策划案中的掷骰子,先随机得到骰子的总和,再将骰子拆分成三个随机的骰子数,策划案中说明有对出现豹子进行控制,这边不把这个实现做进来
|
||||||
|
如果需要进行控制,则在获取结果之后进行控制即可,重新掷骰子的概率不会特别高,因为豹子本身就是一个低概率的事件。
|
||||||
|
|
||||||
|
|
||||||
|
## 实现
|
||||||
|
总共两个实现,一个是实际需求中的三个数的拆分
|
||||||
|
|
||||||
|
另一个是N个数的拆分,这边用Splitter结构体实现,在创建的时候需要进行数字与数量的校验
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangZJ
|
||||||
|
* @Time : 2021/6/16 10:50
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package splitNumToN
|
||||||
|
|
||||||
|
import (
|
||||||
|
"Go-Tool/util/rand"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
//将一个数拆解成三个
|
||||||
|
func SplitNumTo3(num int) {
|
||||||
|
randNumList := make([]int, 0)
|
||||||
|
var count int
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
randNum := getRandValue(num-count, 3-1-i)
|
||||||
|
randNumList = append(randNumList, randNum)
|
||||||
|
count = count + randNum
|
||||||
|
}
|
||||||
|
|
||||||
|
randNumList = append(randNumList, num-count)
|
||||||
|
|
||||||
|
for _, num := range randNumList {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//num 被随机的数
|
||||||
|
//count count + 1 = 总随机数数量
|
||||||
|
func getRandValue(num int, count int) int {
|
||||||
|
minValue := num - 6*count
|
||||||
|
if minValue <= 0 {
|
||||||
|
minValue = 1
|
||||||
|
}
|
||||||
|
maxValue := num - count*1
|
||||||
|
if maxValue > 6 {
|
||||||
|
maxValue = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
return rand.GetRandInt(minValue, maxValue)
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangZJ
|
||||||
|
* @Time : 2021/6/16 10:52
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package splitNumToN
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSplitNumTo3(t *testing.T) {
|
||||||
|
for i := 4; i <= 17; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 100; j++ {
|
||||||
|
fmt.Println()
|
||||||
|
SplitNumTo3(i)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangZJ
|
||||||
|
* @Time : 2021/6/15 11:20
|
||||||
|
* @Description:将一个数拆分成其他N个数,这N个数相加的结果等于这个数
|
||||||
|
*/
|
||||||
|
|
||||||
|
package splitNumToN
|
||||||
|
|
||||||
|
import "Go-Tool/util/rand"
|
||||||
|
|
||||||
|
type Splitter struct {
|
||||||
|
NumCount int //拆分成随机数的数量
|
||||||
|
Num int //被拆分的总数
|
||||||
|
MinValue int //被拆分的最小值
|
||||||
|
MaxValue int //被拆分的最大值
|
||||||
|
|
||||||
|
SplitNumList []int //存放拆解之后的结果
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSplitter(numCount, num int) *Splitter {
|
||||||
|
//给定默认的限制的最大最小值
|
||||||
|
splitter := &Splitter{
|
||||||
|
NumCount: numCount,
|
||||||
|
Num: num,
|
||||||
|
MinValue: 1,
|
||||||
|
MaxValue: 6,
|
||||||
|
SplitNumList: make([]int, 0),
|
||||||
|
}
|
||||||
|
//校验数值是否满足
|
||||||
|
splitter.checkValue()
|
||||||
|
return splitter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (splitter *Splitter) checkValue() {
|
||||||
|
if splitter.MinValue*splitter.NumCount > splitter.Num {
|
||||||
|
panic("被拆分的数值过小")
|
||||||
|
}
|
||||||
|
if splitter.MaxValue*splitter.NumCount < splitter.Num {
|
||||||
|
panic("被拆分的数值过大")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//将一个数拆成N个,并且保证N个数相加值等于被拆分的这个数
|
||||||
|
func (splitter *Splitter) SplitNumToN() {
|
||||||
|
var count int
|
||||||
|
for i := 0; i < splitter.NumCount-1; i++ {
|
||||||
|
randNum := splitter.getRandValue(splitter.Num-count, splitter.NumCount-1-i)
|
||||||
|
splitter.SplitNumList = append(splitter.SplitNumList, randNum)
|
||||||
|
count = count + randNum
|
||||||
|
}
|
||||||
|
|
||||||
|
splitter.SplitNumList = append(splitter.SplitNumList, splitter.Num-count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (splitter *Splitter) GetRandNumList() []int {
|
||||||
|
return splitter.SplitNumList
|
||||||
|
}
|
||||||
|
|
||||||
|
//num 被随机的数
|
||||||
|
//count count + 1 = 总随机数数量
|
||||||
|
func (splitter *Splitter) getRandValue(num int, count int) int {
|
||||||
|
minValue := num - splitter.MaxValue*count
|
||||||
|
if minValue <= 0 {
|
||||||
|
minValue = splitter.MinValue
|
||||||
|
}
|
||||||
|
maxValue := num - count*1
|
||||||
|
if maxValue > splitter.MaxValue {
|
||||||
|
maxValue = splitter.MaxValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return rand.GetRandInt(minValue, maxValue)
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangZJ
|
||||||
|
* @Time : 2021/6/16 9:50
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package splitNumToN
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSplitNumToNWith2(t *testing.T) {
|
||||||
|
|
||||||
|
fmt.Println("测试两个数的情况")
|
||||||
|
for i := 3; i <= 11; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 20; j++ {
|
||||||
|
splitter := NewSplitter(2, i)
|
||||||
|
splitter.SplitNumToN()
|
||||||
|
for _, num := range splitter.GetRandNumList() {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitNumToNWith3(t *testing.T) {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("测试三个数的情况")
|
||||||
|
for i := 4; i <= 17; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 20; j++ {
|
||||||
|
splitter := NewSplitter(3, i)
|
||||||
|
fmt.Println()
|
||||||
|
splitter.SplitNumToN()
|
||||||
|
for _, num := range splitter.GetRandNumList() {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitNumToNWith4(t *testing.T) {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("测试四个数的情况")
|
||||||
|
for i := 5; i <= 23; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 100; j++ {
|
||||||
|
splitter := NewSplitter(4, i)
|
||||||
|
fmt.Println()
|
||||||
|
splitter.SplitNumToN()
|
||||||
|
for _, num := range splitter.GetRandNumList() {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitNumToNWith5(t *testing.T) {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("测试五个数的情况")
|
||||||
|
for i := 6; i <= 29; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 100; j++ {
|
||||||
|
splitter := NewSplitter(5, i)
|
||||||
|
fmt.Println()
|
||||||
|
splitter.SplitNumToN()
|
||||||
|
for _, num := range splitter.GetRandNumList() {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSplitNumToNWith6(t *testing.T) {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("测试六个数的情况")
|
||||||
|
for i := 7; i <= 35; i++ {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("当前随机数为%d", i))
|
||||||
|
for j := 0; j < 100; j++ {
|
||||||
|
splitter := NewSplitter(6, i)
|
||||||
|
fmt.Println()
|
||||||
|
splitter.SplitNumToN()
|
||||||
|
for _, num := range splitter.GetRandNumList() {
|
||||||
|
fmt.Print(fmt.Sprintf("%d ", num))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,13 +14,15 @@ import (
|
|||||||
func TestHorspool(t *testing.T) {
|
func TestHorspool(t *testing.T) {
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "abcd")) //输出0
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "abcd")) //输出0
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "bcd")) //输出1
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "bcd")) //输出1
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "fgh")) //输出6
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "fgh")) //输出5
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "hijk")) //输出8
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "hijk")) //输出7
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "jk")) //输出10
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "jk")) //输出9
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "k")) //输出11
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "k")) //输出10
|
||||||
|
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kbz")) //输出-1
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kbz")) //输出-1
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kdasdsad")) //输出-1
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "kdasdsad")) //输出-1
|
||||||
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "dsadsa")) //输出-1
|
fmt.Println("该子串的位置为:", Horspool("abcdefghijk", "dsadsa")) //输出-1
|
||||||
|
|
||||||
|
fmt.Println(shiTable("abdabe"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/24 13:19
|
||||||
|
* @Description:KMP字符串匹配算法,参考地址:https://www.cnblogs.com/en-heng/p/5091365.html
|
||||||
|
* http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
func KmpMatch(allString string, match string) int {
|
||||||
|
next := getNext(match)
|
||||||
|
i := 0 //被匹配的字符串下标
|
||||||
|
j := 0 //模式匹配字符串下标
|
||||||
|
sLength := len(allString) - 1
|
||||||
|
mLength := len(match) - 1
|
||||||
|
for i <= sLength && j <= mLength {
|
||||||
|
if j == -1 || allString[i] == match[j] {
|
||||||
|
j++
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
j = next[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if j == len(match) {
|
||||||
|
return i - j
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
//失配表函数构建(部分匹配函数)
|
||||||
|
func getNext(match string) []int {
|
||||||
|
next := make([]int, len(match))
|
||||||
|
next[0] = -1
|
||||||
|
i := 0
|
||||||
|
j := -1
|
||||||
|
|
||||||
|
mLength := len(match) - 1
|
||||||
|
|
||||||
|
for i < mLength {
|
||||||
|
//处理两种情况: 1.数组第一个数是-1 2. match对应位置字符相等的情况
|
||||||
|
if j == -1 || match[i] == match[j] {
|
||||||
|
//如果这里是数组第一个数的时候,下标要往后移动
|
||||||
|
//如果这里是数组相等的情况,要比较下一个相应的字符,所以下标需要往后移动,而next需要在上一个的基础上去做+1操作
|
||||||
|
i++
|
||||||
|
j++
|
||||||
|
next[i] = j
|
||||||
|
} else {
|
||||||
|
//如果匹配过程中,出现对应不上的情况,也就是说 match[i] != match[j],
|
||||||
|
j = next[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/24 17:52
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKmpMatch(t *testing.T) {
|
||||||
|
s := "abcbvxs"
|
||||||
|
m := "bcb"
|
||||||
|
showResult(s, m)
|
||||||
|
s = "abcbvxs"
|
||||||
|
m = "bx"
|
||||||
|
showResult(s, m)
|
||||||
|
s = "abcbvxssdaadsad"
|
||||||
|
m = "cbvxssdaa"
|
||||||
|
showResult(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchNum(t *testing.T) {
|
||||||
|
s := "ababababca"
|
||||||
|
m := "abababca"
|
||||||
|
showResult(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func showResult(s, m string) {
|
||||||
|
i := KmpMatch(s, m)
|
||||||
|
if i == -1 {
|
||||||
|
fmt.Println("未找到对应字符串")
|
||||||
|
} else {
|
||||||
|
fmt.Println(fmt.Sprintf("匹配到的字符串是:%v", s[i:len(m)+i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetNext(t *testing.T) {
|
||||||
|
next := getNext("abababca")
|
||||||
|
fmt.Println(next)
|
||||||
|
next1 := getNext("abababc")
|
||||||
|
fmt.Println(next1)
|
||||||
|
next2 := getNext("abababcxy")
|
||||||
|
fmt.Println(next2)
|
||||||
|
next3 := getNext("abababcxyxyy")
|
||||||
|
fmt.Println(next3)
|
||||||
|
next4 := getNext("abcdabd")
|
||||||
|
fmt.Println(next4)
|
||||||
|
next5 := getNext("abcxabcxabcyabcz")
|
||||||
|
fmt.Println(next5)
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/5 13:17
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
func KarpRabinMatch(allString, modeString string) int {
|
||||||
|
hashMode := hash(modeString)
|
||||||
|
for i := 0; i < len(allString)-len(modeString)+1; i++ {
|
||||||
|
hashKey := hash(allString[i : i+len(modeString)+1])
|
||||||
|
if hashMode == hashKey {
|
||||||
|
for j := 0; j < len(modeString); j++ {
|
||||||
|
if allString[i+j] != modeString[j] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(s string) int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/5 13:25
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKarpRabinMatch(t *testing.T) {
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "abcd")) //输出0
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "bcd")) //输出1
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "fgh")) //输出5
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "hijk")) //输出7
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "jk")) //输出9
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "k")) //输出10
|
||||||
|
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "kbz")) //输出-1
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "kdasdsad")) //输出-1
|
||||||
|
fmt.Println("该子串的位置为:", KarpRabinMatch("abcdefghijk", "dsadsa")) //输出-1
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/8 14:42
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func ShiftAndMatch(allString, modeString string) int {
|
||||||
|
if len(modeString) > 32 {
|
||||||
|
panic("暂只支持32位大小")
|
||||||
|
}
|
||||||
|
|
||||||
|
bitap := GenerateTable(modeString)
|
||||||
|
|
||||||
|
fmt.Println("bitap的二进制:")
|
||||||
|
for i := 0; i < len(modeString); i++ {
|
||||||
|
fmt.Println(fmt.Sprintf("当前字符:%c,对应二进制:%08b", modeString[i], bitap[modeString[i]-'a']))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
|
var status int
|
||||||
|
for i := 0; i < len(allString); i++ {
|
||||||
|
status = ((status << 1) | 1) & bitap[allString[i]-'a']
|
||||||
|
fmt.Println(fmt.Sprintf("当前字符:%c,对应的二进制结果:%08b", allString[i], status))
|
||||||
|
if status&(1<<(len(modeString)-1)) > 0 {
|
||||||
|
return i - len(modeString) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateTable(modeString string) []int {
|
||||||
|
bitap := make([]int, 32)
|
||||||
|
for i := 0; i < len(modeString); i++ {
|
||||||
|
bitap[modeString[i]-'a'] |= 1 << i
|
||||||
|
}
|
||||||
|
return bitap
|
||||||
|
}
|
||||||
|
|
||||||
|
func ShiftOrMatch(allString, modeString string) int {
|
||||||
|
if len(modeString) > 32 {
|
||||||
|
panic("暂只支持32位大小")
|
||||||
|
}
|
||||||
|
|
||||||
|
bitap := make([]int, 32)
|
||||||
|
for i := 0; i < 32; i++ {
|
||||||
|
bitap[i] = ^0
|
||||||
|
}
|
||||||
|
|
||||||
|
var shift = 1
|
||||||
|
for i := 0; i < len(modeString); i++ {
|
||||||
|
bitap[modeString[i]-'a'] &= ^shift
|
||||||
|
shift <<= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("bitap的二进制:")
|
||||||
|
for i := 0; i < len(modeString); i++ {
|
||||||
|
fmt.Println(fmt.Sprintf("当前字符:%c,对应二进制:%08b", modeString[i], uint32(bitap[modeString[i]-'a'])))
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
status := ^0
|
||||||
|
mask := ^(1 << (len(modeString) - 1))
|
||||||
|
fmt.Println(fmt.Sprintf("mask:%08b", uint32(mask)))
|
||||||
|
for i := 0; i < len(allString); i++ {
|
||||||
|
status = (status << 1) | bitap[allString[i]-'a']
|
||||||
|
fmt.Println(fmt.Sprintf("当前字符:%c,对应的二进制结果:%08b", allString[i], uint32(status)))
|
||||||
|
if ^(status | mask) > 0 {
|
||||||
|
return i - len(modeString) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/8 14:51
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestShiftAndMatch(t *testing.T) {
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "abcd")) //输出0
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "bcd")) //输出1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "fgh")) //输出5
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "hijk")) //输出7
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "jk")) //输出9
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "k")) //输出10
|
||||||
|
//
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "kbz")) //输出-1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "kdasdsad")) //输出-1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftAndMatch("abcdefghijk", "dsadsa")) //输出-1
|
||||||
|
|
||||||
|
fmt.Println("该子串的位置为:", ShiftAndMatch("cbcbcbaefd", "cbcba"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShiftOrMatch(t *testing.T) {
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "abcd")) //输出0
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "bcd")) //输出1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "fgh")) //输出5
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "hijk")) //输出7
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "jk")) //输出9
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "k")) //输出10
|
||||||
|
//
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "kbz")) //输出-1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "kdasdsad")) //输出-1
|
||||||
|
//fmt.Println("该子串的位置为:", ShiftOrMatch("abcdefghijk", "dsadsa")) //输出-1
|
||||||
|
|
||||||
|
fmt.Println("该子串的位置为:", ShiftOrMatch("cbcbcbaefd", "cbcba"))
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/2 11:21
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
func ShiftTable(mode string) []int {
|
||||||
|
shiftTable := make([]int, 256)
|
||||||
|
|
||||||
|
//一开始设置所有的字符匹配不上向右移动大小为:模式字符串长度 + 1(因为要移动到下一个字符的后一位)
|
||||||
|
for i := range shiftTable {
|
||||||
|
shiftTable[i] = len(mode) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置模式字符串中每一个字符的移动长度.
|
||||||
|
for i := range mode {
|
||||||
|
shiftTable[mode[i]] = len(mode) - i
|
||||||
|
}
|
||||||
|
|
||||||
|
return shiftTable
|
||||||
|
}
|
||||||
|
|
||||||
|
func SundayMatch(allString, modeString string) int {
|
||||||
|
table := ShiftTable(modeString)
|
||||||
|
aLength := len(allString)
|
||||||
|
mLength := len(modeString)
|
||||||
|
i := 0 //这个参数记录的是移动过程中,,模式字符串对应原始字符串的第一个位置.
|
||||||
|
|
||||||
|
for i < aLength-mLength {
|
||||||
|
j := 0
|
||||||
|
for allString[i+j] == modeString[j] {
|
||||||
|
j++
|
||||||
|
if j >= len(modeString) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//找到移动后模式字符串对应原始字符串的第一个位置
|
||||||
|
move := allString[i+mLength]
|
||||||
|
i = i + table[move]
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/3/2 11:21
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSundayMatch(t *testing.T) {
|
||||||
|
s := "abcbvxs"
|
||||||
|
m := "bcb"
|
||||||
|
showResult2(s, m)
|
||||||
|
s = "abcbvxs"
|
||||||
|
m = "bx"
|
||||||
|
showResult2(s, m)
|
||||||
|
s = "abcbvxssdaadsad"
|
||||||
|
m = "cbvxssdaa"
|
||||||
|
showResult2(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func showResult2(s, m string) {
|
||||||
|
i := SundayMatch(s, m)
|
||||||
|
if i == -1 {
|
||||||
|
fmt.Println("未找到对应字符串")
|
||||||
|
} else {
|
||||||
|
fmt.Println(fmt.Sprintf("匹配到的字符串是:%v", s[i:len(m)+i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/25 11:11
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
func ViolentMatch(allString, match string) int {
|
||||||
|
i := 0
|
||||||
|
j := 0
|
||||||
|
sLength := len(allString)
|
||||||
|
mLenght := len(match)
|
||||||
|
|
||||||
|
for i < sLength && j < mLenght {
|
||||||
|
//当前字符如果匹配,继续匹配下一个字符,坐标移动
|
||||||
|
if allString[i] == match[j] {
|
||||||
|
j++
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
//如果字符不匹配,match从头开始,被匹配的字符串从之前匹配的下一个字符开始,坐标修改
|
||||||
|
i = i - j + 1
|
||||||
|
j = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if j == len(match) {
|
||||||
|
return i - j
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @Author : huangzj
|
||||||
|
* @Time : 2021/2/25 11:11
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stringMatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestViolentMatch(t *testing.T) {
|
||||||
|
s := "abcbvxs"
|
||||||
|
m := "bcb"
|
||||||
|
showResult1(s, m)
|
||||||
|
s = "abcbvxs"
|
||||||
|
m = "bx"
|
||||||
|
showResult1(s, m)
|
||||||
|
s = "abcbvxssdaadsad"
|
||||||
|
m = "cbvxssdaa"
|
||||||
|
showResult1(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func showResult1(s, m string) {
|
||||||
|
i := ViolentMatch(s, m)
|
||||||
|
if i == -1 {
|
||||||
|
fmt.Println("未找到对应字符串")
|
||||||
|
} else {
|
||||||
|
fmt.Println(fmt.Sprintf("匹配到的字符串是:%v", s[i:len(m)+i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,15 @@ func TestTimeIntervalUtil(t *testing.T) {
|
|||||||
o2 := GetIntervalBetweenTimes(time.Now().AddDate(3, 2, 5).Add(5*time.Hour).Add(7*time.Minute).Add(10*time.Second).Unix(), time.Now().Unix())
|
o2 := GetIntervalBetweenTimes(time.Now().AddDate(3, 2, 5).Add(5*time.Hour).Add(7*time.Minute).Add(10*time.Second).Unix(), time.Now().Unix())
|
||||||
o3 := GetIntervalBetweenTimes(time.Now().Unix(), time.Now().AddDate(3, -2, 5).Add(5*time.Hour).Add(7*time.Minute).Add(10*time.Second).Unix())
|
o3 := GetIntervalBetweenTimes(time.Now().Unix(), time.Now().AddDate(3, -2, 5).Add(5*time.Hour).Add(7*time.Minute).Add(10*time.Second).Unix())
|
||||||
|
|
||||||
|
O4 := GetIntervalDay(time.Now(), time.Now().AddDate(0, 0, 2))
|
||||||
|
O5 := GetIntervalDay(time.Now(), time.Now().AddDate(0, 0, 2).Add(5*time.Hour))
|
||||||
|
O6 := GetIntervalDay(time.Now(), time.Now().AddDate(0, 0, 2).Add(25*time.Hour))
|
||||||
|
|
||||||
|
fmt.Println("相差天数计算:")
|
||||||
|
fmt.Println(O4)
|
||||||
|
fmt.Println(O5)
|
||||||
|
fmt.Println(O6)
|
||||||
|
|
||||||
ox := GetIntervalBetweenTimes(time.Now().Unix(), time.Date(2020, 5, 6, 0, 0, 0, 0, time.Local).Unix())
|
ox := GetIntervalBetweenTimes(time.Now().Unix(), time.Date(2020, 5, 6, 0, 0, 0, 0, time.Local).Unix())
|
||||||
fmt.Println(ox)
|
fmt.Println(ox)
|
||||||
|
|
||||||
|
|||||||
@@ -136,6 +136,20 @@ func GetIntervalBetweenTimes(timestamp, stamp int64) vo.IntervalObj {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取两个时间点之间相差多少天
|
||||||
|
func GetIntervalDay(beforeTime, afterTime time.Time) int {
|
||||||
|
timestamp := beforeTime.Unix()
|
||||||
|
stamp := afterTime.Unix()
|
||||||
|
//时间大小保证前小后大
|
||||||
|
if timestamp > stamp {
|
||||||
|
timestamp, stamp = stamp, timestamp
|
||||||
|
}
|
||||||
|
timeBefore := time.Unix(timestamp, 0)
|
||||||
|
timeAfter := time.Unix(stamp, 0)
|
||||||
|
m := timeAfter.Sub(timeBefore)
|
||||||
|
return int(m.Hours() / 24)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param timestamp 时间戳
|
* @param timestamp 时间戳
|
||||||
* @param stamp 时间戳
|
* @param stamp 时间戳
|
||||||
|
|||||||
+10
-2
@@ -32,7 +32,7 @@ func initTrie() *Trie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//往前缀树中添加对应的字符串(build模式)
|
//往前缀树中添加对应的字符串(build模式)
|
||||||
func (trie *Trie) insert(word string) *Trie {
|
func (trie *Trie) Insert(word string) *Trie {
|
||||||
traverse := trie
|
traverse := trie
|
||||||
for _, v := range []rune(word) {
|
for _, v := range []rune(word) {
|
||||||
if _, ok := traverse.Child[v]; !ok {
|
if _, ok := traverse.Child[v]; !ok {
|
||||||
@@ -48,13 +48,21 @@ func (trie *Trie) insert(word string) *Trie {
|
|||||||
//删除对应的字符串,如果查找不到则直接返回(build模式)
|
//删除对应的字符串,如果查找不到则直接返回(build模式)
|
||||||
func (trie *Trie) Delete(word string) *Trie {
|
func (trie *Trie) Delete(word string) *Trie {
|
||||||
traverse := trie
|
traverse := trie
|
||||||
|
parent := trie
|
||||||
|
var value rune
|
||||||
for _, v := range []rune(word) {
|
for _, v := range []rune(word) {
|
||||||
if _, ok := traverse.Child[v]; !ok {
|
if _, ok := traverse.Child[v]; !ok {
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
parent = traverse
|
||||||
traverse = traverse.Child[v]
|
traverse = traverse.Child[v]
|
||||||
|
value = v
|
||||||
}
|
}
|
||||||
traverse.Word = emptyTag
|
if len(parent.Child) == 0 {
|
||||||
|
delete(parent.Child, value)
|
||||||
|
return trie
|
||||||
|
}
|
||||||
|
parent.Child[value].Word = emptyTag
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-10
@@ -14,15 +14,16 @@ import (
|
|||||||
//模糊查询前缀匹配的所有字符串
|
//模糊查询前缀匹配的所有字符串
|
||||||
func TestSearchTrieVague(t *testing.T) {
|
func TestSearchTrieVague(t *testing.T) {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("模糊查询 查找前缀匹配的所有字符串")
|
fmt.Println("模糊查询 查找前缀匹配的所有字符串,输入\"新年快乐\" ")
|
||||||
trie := New()
|
trie := New()
|
||||||
trie.insert("abcuuid").insert("abcuued").insert("abcMxns").insert("abssde").insert("avddfa")
|
trie.Insert("abcuuid").Insert("abcuued").Insert("abcMxns").Insert("abssde").Insert("avddfa")
|
||||||
trie.insert("我爱中国").insert("我爱祖国").insert("我爱学习").insert("我是谁").insert("我在哪里")
|
trie.Insert("我爱中国").Insert("我爱祖国").Insert("我爱学习").Insert("我是谁").Insert("我在哪里")
|
||||||
trie.insert("我是你").insert("我").insert("我喜欢学习").insert("我在厦门").insert("我是一个程序员")
|
trie.Insert("我是你").Insert("我").Insert("我喜欢学习").Insert("我在厦门").Insert("我是一个程序员")
|
||||||
|
trie.Insert("新年快乐,你好呀").Insert("新年新气象").Insert("新的一年新的开始")
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
result3, _ := trie.SearchTrieVague("我爱她")
|
result3, _ := trie.SearchTrieVague("新年快乐")
|
||||||
for _, r := range result3 {
|
for _, r := range result3 {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
}
|
}
|
||||||
@@ -33,8 +34,8 @@ func TestSearchTrie(t *testing.T) {
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("查找前缀匹配的所有字符串")
|
fmt.Println("查找前缀匹配的所有字符串")
|
||||||
trie := New()
|
trie := New()
|
||||||
trie.insert("abcuuid").insert("abcuued").insert("abcMxns").insert("abssde").insert("avddfa")
|
trie.Insert("abcuuid").Insert("abcuued").Insert("abcMxns").Insert("abssde").Insert("avddfa")
|
||||||
trie.insert("我爱中国").insert("我爱祖国").insert("我爱学习").insert("我是谁").insert("我在哪里")
|
trie.Insert("我爱中国").Insert("我爱祖国").Insert("我爱学习").Insert("我是谁").Insert("我在哪里")
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
@@ -62,7 +63,7 @@ func TestSearchTrie(t *testing.T) {
|
|||||||
//敏感词汇屏蔽测试
|
//敏感词汇屏蔽测试
|
||||||
func TestSensitiveWordsTest(t *testing.T) {
|
func TestSensitiveWordsTest(t *testing.T) {
|
||||||
trie := New()
|
trie := New()
|
||||||
trie.insert("粗话").insert("fuck").insert("fuckk").insert("脏话")
|
trie.Insert("粗话").Insert("fuck").Insert("fuckk").Insert("脏话")
|
||||||
s := "我是脏话,我是粗话,fuckk,fuck,fffuccck"
|
s := "我是脏话,我是粗话,fuckk,fuck,fffuccck"
|
||||||
word := trie.DealFunc(s, func(sentence []rune, start int, end int) string {
|
word := trie.DealFunc(s, func(sentence []rune, start int, end int) string {
|
||||||
var replace string
|
var replace string
|
||||||
@@ -73,13 +74,14 @@ func TestSensitiveWordsTest(t *testing.T) {
|
|||||||
runes = append(runes, sentence[end:]...)
|
runes = append(runes, sentence[end:]...)
|
||||||
return string(runes)
|
return string(runes)
|
||||||
})
|
})
|
||||||
fmt.Println(word)
|
fmt.Println(fmt.Sprintf("原来的字符串: \"%v\"", s))
|
||||||
|
fmt.Println(fmt.Sprintf("转换后的字符串: \"%v\"", word))
|
||||||
}
|
}
|
||||||
|
|
||||||
//常规功能测试
|
//常规功能测试
|
||||||
func TestCommonTest(t *testing.T) {
|
func TestCommonTest(t *testing.T) {
|
||||||
trie := New()
|
trie := New()
|
||||||
trie.insert("ABC").insert("AB").insert("ABE").insert("ABEX").insert("XYZ").insert("你").insert("你好").insert("你是谁")
|
trie.Insert("ABC").Insert("AB").Insert("ABE").Insert("ABEX").Insert("XYZ").Insert("你").Insert("你好").Insert("你是谁")
|
||||||
result := trie.Traverse()
|
result := trie.Traverse()
|
||||||
for _, r := range result {
|
for _, r := range result {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
|
|||||||
Reference in New Issue
Block a user