Compare commits

..

9 Commits
v0.1 ... master

Author SHA1 Message Date
NorthCityChen
ed3284d5b6 ADD: math.A && math.C 2022-05-03 18:52:56 +08:00
NorthCityChen
d00014020c ADD: BIT 2022-04-26 17:09:56 +08:00
NorthCityChen
e789b95c8f fix: heap 2022-04-26 15:57:00 +08:00
NorthCityChen
0ab851e49f ADD:heap 2022-04-26 14:26:02 +08:00
NorthCityChen
cecb8fe8fb ADD: randstr 2022-04-04 16:12:23 +08:00
NorthCityChen
2cb1a5c174 ADD: randstr 2022-04-04 16:10:57 +08:00
NorthCityChen
9b0c409a97 ADD: sqrt & Exp2 2022-04-03 09:33:42 +08:00
NorthCityChen
89a281434c ADD: readme 2022-04-02 14:30:40 +08:00
NorthCityChen
18524064a5 ADD: readme 2022-04-02 14:24:59 +08:00
9 changed files with 369 additions and 37 deletions

34
app.go
View File

@ -1,6 +1,6 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-02 13:19:42
* @LastEditTime: 2022-05-03 18:51:46
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
@ -10,28 +10,18 @@ package main
import (
"fmt"
"gitee.com/NorthCityChen/stl-go/dequeue"
"gitee.com/NorthCityChen/stl-go/math"
)
var a = []int{1, 2, 65, 4, 33, 5}
func main() {
q := dequeue.Init[int]()
q.LPush(12)
q.LPush(23)
q.LPush(34)
q.Clear()
q.LPush(34)
q.RPush(44)
fmt.Println(q.LPop())
fmt.Println(q.LPop())
fmt.Println(q.LPop())
fmt.Println(q.LPop())
// q := queue.Init[int]()
// q.Push(12)
// q.Push(23)
// q.Push(44)
// // q.IsEmpty()
// fmt.Println(q.Pop())
// fmt.Println(q.Pop())
// fmt.Println(q.Pop())
// fmt.Println(q.Pop())
// h := heap.Init(a, heap.MinHeap[int]())
// fmt.Println(h)
ans := math.C(8, 2)
fmt.Println(ans)
ans = math.A(12, 2)
fmt.Println(ans)
}

55
bit/bit.go Normal file
View File

@ -0,0 +1,55 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-26 17:08:18
* @Description: Binary Indexed Trees
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package bit
type Number interface {
int | int64 | float32 | float64
}
type bit[T Number] struct {
array []T
brray []T
len int
}
func lowbit(x int) int {
return x & -x
}
// 初始化一个树状数组
func Init[T Number](array []T) bit[T] {
ret := bit[T]{
array: append([]T{0}, array...),
brray: make([]T, len(array)+5),
len: len(array),
}
for i := 1; i < len(ret.array); i++ {
ret.Add(i, ret.array[i])
}
return ret
}
// 在第x个数的位置+k
func (b *bit[T]) Add(x int, k T) {
for x <= b.len {
b.brray[x] = b.brray[x] + k
x = x + lowbit(x) // 父节点
}
}
// 求第一个数到第x个数的和
func (b *bit[T]) Ask(x int) T {
var ans T = 0
for x >= 1 {
ans = ans + b.brray[x]
x = x - lowbit(x)
}
return ans
}

View File

@ -1,6 +1,6 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-02 12:39:15
* @LastEditTime: 2022-04-27 13:31:14
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
@ -8,7 +8,7 @@
package dequeue
type Number interface {
int | int64 | float32 | float64
int | int64 | float32 | float64 | string
}
// dequeue: Based on Double Linked List
@ -24,6 +24,9 @@ type dequeueNode[T Number] struct {
RPointer *dequeueNode[T]
}
// 返回对应类型的零值 对比 T(Rune(0))在获取空字符串的情况下快14倍左右
func zeroValue[T Number]() (value T) { return }
func Init[T Number]() *Dequeue[T] {
return &Dequeue[T]{size: 0, leftHead: new(dequeueNode[T]), rightHead: new(dequeueNode[T])}
}
@ -50,7 +53,7 @@ func (q *Dequeue[T]) LPush(val T) bool {
func (q *Dequeue[T]) LPop() (T, bool) {
if q.IsEmpty() {
return 0, false
return zeroValue[T](), false
}
val := q.leftHead.Val
q.leftHead = q.leftHead.RPointer
@ -72,7 +75,7 @@ func (q *Dequeue[T]) RPush(val T) bool {
func (q *Dequeue[T]) RPop() (T, bool) {
if q.IsEmpty() {
return 0, false
return zeroValue[T](), false
}
val := q.rightHead.Val
q.rightHead = q.rightHead.LPointer
@ -82,14 +85,14 @@ func (q *Dequeue[T]) RPop() (T, bool) {
func (q *Dequeue[T]) LNode() (T, bool) {
if q.IsEmpty() {
return 0, false
return zeroValue[T](), false
}
return q.leftHead.Val, true
}
func (q *Dequeue[T]) RNode() (T, bool) {
if q.IsEmpty() {
return 0, false
return zeroValue[T](), false
}
return q.rightHead.Val, true
}

50
dequeue/dequeue_test.go Normal file
View File

@ -0,0 +1,50 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-27 13:36:25
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package dequeue
import (
"testing"
// "gitee.com/NorthCityChen/stl-go/dequeue"
)
// type Number interface {
// int | int64 | float32 | float64 | string
// }
// func zeroValue[T Number]() (value T) { return }
func TRune[T Number]() T { return T(rune(0)) }
func BenchmarkZeroValue(b *testing.B) {
for i := 0; i < b.N; i++ {
zeroValue[float64]()
zeroValue[float32]()
zeroValue[int]()
zeroValue[int64]()
zeroValue[string]()
}
}
func BenchmarkTRune(b *testing.B) {
for i := 0; i < b.N; i++ {
TRune[float64]()
TRune[float32]()
TRune[int64]()
TRune[int]()
TRune[string]()
}
}
func BenchmarkRunDequeue(b *testing.B) {
dq := Init[int]()
for i := 0; i < b.N; i++ {
dq.LPush(1)
dq.RPush(2)
dq.LPop()
dq.RPop()
}
}

90
heap/heap.go Normal file
View File

@ -0,0 +1,90 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-27 13:19:36
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package heap
type Number interface {
int | int64 | float32 | float64
}
type heap[T Number] struct {
array []T
len int
cmp func(T, T) bool
}
// 返回对应类型的零值
func zeroValue[T Number]() (value T) { return }
func (h *heap[T]) up(x int) {
for x > 1 && h.cmp(h.array[x], h.array[x/2]) {
h.array[x], h.array[x/2] = h.array[x/2], h.array[x]
x /= 2
}
}
func (h *heap[T]) down(x int) {
for x*2 <= h.len {
t := x * 2
if t+1 <= h.len && h.cmp(h.array[t+1], h.array[t]) {
t++
}
if !h.cmp(h.array[t], h.array[x]) {
break
}
h.array[x], h.array[t] = h.array[t], h.array[x]
x = t
}
}
func (h *heap[T]) Push(v T) {
h.array = append(h.array, v)
h.len++
h.up(h.len)
}
func (h *heap[T]) Pop() T {
if h.len == 0 {
return zeroValue[T]()
}
ret := h.array[1]
h.array[1], h.array[h.len] = h.array[h.len], h.array[1]
h.array = h.array[:h.len]
h.len--
h.down(1)
return ret
}
func (h *heap[T]) Top() T {
return h.array[1]
}
func Init[T Number](array []T, cmp func(T, T) bool) heap[T] {
newArray := make([]T, len(array)+1)
copy(newArray[1:], array)
h := heap[T]{
array: newArray,
len: len(array),
cmp: cmp,
}
for i := h.len; i >= 1; i-- {
h.down(i)
}
return h
}
func MaxHeap[T Number]() func(T, T) bool {
return func(t1, t2 T) bool {
return t1 > t2
}
}
func MinHeap[T Number]() func(T, T) bool {
return func(t1, t2 T) bool {
return t1 < t2
}
}

View File

@ -1,6 +1,6 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-01 21:04:53
* @LastEditTime: 2022-05-03 18:50:22
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
@ -13,10 +13,7 @@ type Number interface {
int | int32 | int64 | float32 | float64
}
func Inf[T Number]() T {
return T(math.Inf(1))
}
// 返回n个数中的最小值
func Max[T Number](arg T, args ...T) T {
var maxNum T = arg
@ -28,6 +25,7 @@ func Max[T Number](arg T, args ...T) T {
return maxNum
}
// 返回n个数中的最大值
func Min[T Number](arg T, args ...T) T {
var minNum T = arg
for _, val := range args {
@ -38,6 +36,7 @@ func Min[T Number](arg T, args ...T) T {
return minNum
}
// 返回n个数的和
func Sum[T Number](args ...T) (sum T) {
for _, val := range args {
sum += val
@ -45,6 +44,7 @@ func Sum[T Number](args ...T) (sum T) {
return sum
}
// 返回num的绝对值
func Abs[T Number](num T) T {
if num < 0 {
num *= -1
@ -52,4 +52,46 @@ func Abs[T Number](num T) T {
return num
}
// sort
// 返回 2**n
func Exp2(num int) int64 {
var ans int64 = 1
for i := 0; i < num; i++ {
ans <<= 1
}
return ans
}
// 返回x的平方根精度比原生略低
func Sqrt(x float64) float64 {
if x < 0 {
return math.NaN()
}
if x == 0 {
return 0
}
last, res := 0.0, 1.0
for last != res {
last = res
res = (res + x/res) / 2
}
return res
}
// 排列数: A(3,1)=3
func A(n, m int) int {
res := 1
for i := m; i >= 1; i-- {
res *= n //n × n-1 × n-2 × ... n-mm就是需要减1的次数
n--
}
return res
}
// 组合数C(3, 2)=3
func C(n, m int) int {
if m == 0 {
return 1
}
return C(n-1, m-1) * (n / m)
}

40
random/random.go Normal file
View File

@ -0,0 +1,40 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-04 19:11:44
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
*/
package random
import (
"math/rand"
"strings"
"time"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
var src = rand.NewSource(time.Now().UnixNano())
func RandStr(strLen int) string {
str := strings.Builder{}
str.Grow(strLen)
for i, cache, remain := strLen-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
str.WriteByte(letterBytes[idx])
i--
}
cache >>= letterIdxBits
remain--
}
return str.String()
}

View File

@ -1,10 +1,72 @@
<!--
* @Author: NorthCity1984
* @LastEditTime: 2022-04-01 13:22:46
* @LastEditTime: 2022-04-02 14:30:28
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.
-->
# stl-go
一些常用的数据结构模板
一个封装了一些简单的数据结构的提供泛型支持的stl库 (go >= 1.18)
# usage
## Dequeue
```go
package main
import (
"fmt"
"gitee.com/NorthCityChen/stl-go/dequeue"
)
func main() {
q := dequeue.Init[int]()
q.LPush(12)
q.LPush(23)
q.LPush(34)
q.Clear()
q.LPush(34)
q.RPush(44)
fmt.Println(q.LPop())
fmt.Println(q.LPop())
fmt.Println(q.LPop())
fmt.Println(q.LPop())
}
```
## Queue
```go
import (
"fmt"
"gitee.com/NorthCityChen/stl-go/queue"
)
func main() {
q := queue.Init[int]()
q.Push(12)
q.Push(23)
q.Push(44)
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.Pop())
}
```
# RoadMap
- [x] 双端队列
- [x] 队列
- [x] 栈
- [x] 数学
- [ ] 优先队列
- [ ] 红黑树
- [ ] 集合
- [ ] 二分查找
- [ ] 下一个排序组合

View File

@ -1,6 +1,6 @@
/*
* @Author: NorthCity1984
* @LastEditTime: 2022-04-02 13:19:33
* @LastEditTime: 2022-04-13 21:41:20
* @Description:
* @Website: https://grimoire.cn
* Copyright (c) NorthCity1984 All rights reserved.