1 Star 0 Fork 0

andrew.zhang / libgo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
arrayutil.go 5.35 KB
一键复制 编辑 原始数据 按行查看 历史
andrew.zhang 提交于 2022-10-31 06:14 . 整理以前代码中...
package zbutil
import (
"sort"
"gitee.com/cosmiczh/libgo/zbcmn"
)
type _sort_ struct {
m_len int
mf_less func(i, j int) bool
mf_swap func(i, j int)
}
func (this *_sort_) Len() int {
return this.m_len
}
func (this *_sort_) Less(i, j int) bool {
return this.mf_less(i, j)
}
func (this *_sort_) Swap(i, j int) {
this.mf_swap(i, j)
}
// Sort 使用快速排序算法排序序列
func Sort(nlen int, fless func(i, j int) bool, fswap func(i, j int)) {
sort.Sort(&_sort_{m_len: nlen, mf_less: fless, mf_swap: fswap})
}
// SortArr 使用快速排序算法排序内建可排序类型的序列
func SortArr[A zbcmn.Ordered](a ...A) []A {
sort.Sort(&_sort_{m_len: len(a),
mf_less: func(i, j int) bool { return a[i] < a[j] },
mf_swap: func(i, j int) { a[i], a[j] = a[j], a[i] },
})
return a
}
// InSet 是否在一个集合中
func InSet[T comparable](a T, set ...T) bool {
return Index(set, a) >= 0
}
// Index 查找第一个索引
func Index[T comparable](arr []T, val T) int {
for i, nlen := 0, len(arr); i < nlen; i++ {
if arr[i] == val {
return i
}
}
return -1
}
// Reverse 颠倒存储序列内容
func Reverse(nlen int, fswap func(i, j int)) {
for i, len := 0, nlen/2; i < len; i++ {
fswap(i, nlen-1-i)
}
}
// CountFunc 计算符合条件的序列项总数
func CountFunc(nlen int, cond func(i int) bool) int {
l_count := 0
for i := 0; i < nlen; i++ {
if cond(i) {
l_count++
}
}
return l_count
}
// IndexFunc 正向搜索符合条件的项目,返回第一个下标
func IndexFunc(nlen int, cond func(i int) bool) int {
for i := 0; i < nlen; i++ {
if cond(i) {
return i
}
}
return -1
}
// IndexFunc 反向搜索符合条件的项目,返回第一个下标
func IndexLastFunc(nlen int, cond func(i int) bool) int {
for i := nlen - 1; i >= 0; i-- {
if cond(i) {
return i
}
}
return -1
}
// TraverseFunc 跳跃遍历
func TraverseFunc(nlen int, skip func(i int) int) {
for i := 0; i < nlen; i++ {
if i += skip(i); i < -1 {
i = -1
}
}
}
// Lowerbound 二分查找,复杂度O(n)=log2_n 返回>={搜索值}的最小索引,fmore_eq:=func(i int)bool{return arr[i]>={搜索值}}
func Lowerbound(nlen int, fmore_eq func(i int) bool) int {
return sort.Search(nlen, fmore_eq)
}
// Upperbound 二分查找,复杂度O(n)=log2_n 返回>{搜索值}的最小索引,fmore:=func(i int)bool{return arr[i]>{搜索值}}
func Upperbound(neln int, fmore func(j int) bool) int {
return sort.Search(neln, fmore)
}
// IndexScope 返回已排序序列[]T中介于半闭包区间[_Left,_Right)的下标范围
func IndexScope[T zbcmn.Ordered](a []T, _Left, _Right T) (int, int) {
return Lowerbound(len(a), func(i int) bool { return a[i] >= _Left }),
Upperbound(len(a), func(i int) bool { return a[i] > _Right })
}
/*--------------------------------------------------------------------
* 序列数据 去重复
*/
// MakeUnique2 简化版的MakeUnique 使 序列数据 去重复
func MakeUnique2(nlen int, less func(i, j int) bool, swap func(i, j int)) (deletedcount int) {
return MakeUnique(nlen, less, swap, func(i, j int) bool { return !less(i, j) && !less(j, i) }, swap)
}
// MakeUnique 算法工具函数 使 序列数据 去重复
func MakeUnique(nlen int, less func(i, j int) bool, swap func(i, j int), equal func(i, j int) bool, assign func(i, j int)) (deletedcount int) {
if nlen < 2 {
return 0
}
Sort(nlen, less, swap)
deletedcount = 0
for i := 1; i < nlen-deletedcount; i++ {
if equal(i-1, i+deletedcount) {
deletedcount++
i--
continue
}
if deletedcount > 0 {
assign(i, i+deletedcount)
}
}
return
}
// MakeUniqueType 使内置可排序类型 序列数据 去重复
func MakeUniqueType[T zbcmn.Ordered](arr ...T) []T {
l_deletedcount := MakeUnique(len(arr),
func(i, j int) bool { return arr[i] < arr[j] },
func(i, j int) { arr[i], arr[j] = arr[j], arr[i] },
func(i, j int) bool { return arr[i] == arr[j] },
func(i, j int) { arr[i] = arr[j] })
return arr[:len(arr)-l_deletedcount]
}
/*--------------------------------------------------------------------
* 序列数据 多删除
*/
// DelNotCond 删除不符合条件的多个序列元素,调用方需在finish中去掉末尾的deletedcount个元素
func DelNotCond(nlen int, fassign func(i, j int), keepcond func(i int) bool, finish func(deletedcount int)) bool {
var l_deletedidx []int
for i := 0; i < nlen; i++ {
if !keepcond(i) {
l_deletedidx = append(l_deletedidx, i)
}
}
l_deletedcount := DelMulti(nlen, fassign, l_deletedidx...)
finish(l_deletedcount)
return nlen < 1 || nlen > l_deletedcount
}
// DelMulti 删除序列数据中多个下标的数据,调用方需自行缩短序列的长度去掉末尾的deletedcount个元素
func DelMulti[IDX zbcmn.Integer](nlen int, fassign func(i, j IDX), deletedidx ...IDX) (deletedcount int) {
if len(deletedidx) < 1 {
return 0
} else if len(deletedidx) > 2 {
deletedidx = MakeUniqueType(deletedidx...)
}
for i := 0; i < len(deletedidx); i++ {
if deletedidx[i] >= 0 {
deletedidx = deletedidx[i:]
break
}
}
if len(deletedidx) < 1 {
return 0
}
if nlen := IDX(nlen); deletedidx[len(deletedidx)-1] < nlen {
deletedidx = append(deletedidx, nlen) //末尾一定要追加一个大数
}
var l_deleted IDX = 0
for i, movi, nlen := deletedidx[0], deletedidx[0], IDX(nlen); movi < nlen; movi++ {
if movi == deletedidx[l_deleted] {
l_deleted++
} else {
fassign(i, movi)
i++
}
}
return int(l_deleted)
}
Go
1
https://gitee.com/andrewzh/libgo.git
git@gitee.com:andrewzh/libgo.git
andrewzh
libgo
libgo
v1.0.3

搜索帮助