first commit

This commit is contained in:
2022-12-24 17:48:08 +02:00
commit 57c4f8e7b9
6 changed files with 2513 additions and 0 deletions

198
arr.go Normal file
View File

@@ -0,0 +1,198 @@
package bin
func DeleteArrElem(arr []byte, qty int, elemSize int, idx int) {
dstIdx := elemSize * idx
srcIdx := dstIdx + elemSize
end := qty * elemSize
for ; srcIdx < end; srcIdx++ {
arr[dstIdx] = arr[srcIdx]
dstIdx++
}
for i := elemSize * (qty - 1); i < end; i++ {
arr[i] = 0
}
}
func InsertArrElem(arr []byte, qty int, elem []byte, idx int) {
elemSize := len(elem)
srcIdx := qty*elemSize - 1 // last byte
dstIdx := srcIdx + elemSize
end := elemSize * idx
for ; srcIdx >= end; srcIdx-- {
arr[dstIdx] = arr[srcIdx]
dstIdx--
}
// Вставляем элемент
for _, b := range elem {
arr[end] = b
end++
}
}
// Для массивов, которые начинаются с конца arr и движутся к началу
func DeleteReverseArrElem(arr []byte, qty int, elemSize int, idx int) {
dstIdx := len(arr) - idx*elemSize - 1
srcIdx := dstIdx - elemSize
end := len(arr) - qty*elemSize
for ; srcIdx >= end; srcIdx-- {
arr[dstIdx] = arr[srcIdx]
dstIdx--
}
for i := end; i < end+elemSize; i++ {
arr[i] = 0
}
}
// qty = 2
// 0 0 3 3 1 1
// 3 3 3 3 1 1
func InsertReverseArrElem(arr []byte, qty int, elem []byte, idx int) {
elemSize := len(elem)
srcIdx := len(arr) - qty*elemSize
dstIdx := srcIdx - elemSize
end := len(arr) - elemSize*idx
for ; srcIdx < end; srcIdx++ {
arr[dstIdx] = arr[srcIdx]
dstIdx++
}
// Вставляем элемент
i := end - elemSize
for _, b := range elem {
arr[i] = b
i++
}
}
// Предполагается что значения отсортированы ASC
func FindArrElem(arr []byte, qty int, elem []byte, byteOrder ByteOrder) (elemIdx int, isFound bool) {
if qty == 0 {
return
}
// Границы (индексы элементов массива)
a := 0
b := qty - 1
for {
elemIdx = (b-a)/2 + a
code := compareToArrElem(arr, elem, elemIdx, byteOrder)
if code == 1 {
a = elemIdx + 1
if a > b {
return elemIdx + 1, false
}
} else if code == -1 {
b = elemIdx - 1
if b < a {
return elemIdx, false
}
} else {
return elemIdx, true
}
}
}
// -1, меньше
// 1, больше
// 0, равны
func compareToArrElem(arr []byte, elem []byte, elemIdx int, byteOrder ByteOrder) int {
if byteOrder == HL {
// индекс первого байта
idx := elemIdx * len(elem)
for _, b := range elem {
if b > arr[idx] {
return 1
} else if b < arr[idx] {
return -1
}
idx++
}
} else {
// индекс последнего байта
idx := (elemIdx+1)*len(elem) - 1
for bIdx := len(elem) - 1; bIdx >= 0; bIdx-- {
b := elem[bIdx]
if b > arr[idx] {
return 1
} else if b < arr[idx] {
return -1
}
idx--
}
}
return 0
}
// func find(arr []int, num int) (int, bool) {
// var a, b, i int
// b = len(arr) - 1
// for {
// i = (b-a)/2 + a
// if num > arr[i] {
// a = i + 1
// if a > b {
// return i + 1, false
// }
// } else if num < arr[i] {
// b = i - 1
// if b < a {
// return i, false
// }
// } else {
// return i, true
// }
// }
// }
type KeyComparator interface {
CompareTo(int) int
}
// Предполагается что значения отсортированы ASC
func BinarySearch(qty int, keyComparator KeyComparator) (elemIdx int, isFound bool) {
if qty == 0 {
return
}
// Границы (индексы элементов массива)
a := 0
b := qty - 1
for {
elemIdx = (b-a)/2 + a
code := keyComparator.CompareTo(elemIdx)
if code == 1 {
a = elemIdx + 1
if a > b {
return elemIdx + 1, false
}
} else if code == -1 {
b = elemIdx - 1
if b < a {
return elemIdx, false
}
} else {
return elemIdx, true
}
}
}