ads1_2021/code/golang/pkg/algorithms/search/jump/jump.go

97 lines
2.5 KiB
Go
Raw Normal View History

package jump
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/pkg/algorithms/search/sequential"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* ALGORITHM jump search
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
Annahmen:
- L sei aufsteigend sortiert.
- Idealerweise: L enthält keine Duplikate.
- Idealerweise: Abstände zw. Elementen nicht uniform.
Outputs: Position von x in L, sonst 1 wenn x nicht in L.
*/
func JumpSearchLinear(L []int, x int, m int) int {
i0 := 0
i1 := m
// ACHTUNG: dies ist eine while-Schleife ist golang:
for i0 < len(L) {
metrics.AddTimeCost()
if i1 > len(L) {
i1 = len(L)
}
block := L[i0:i1]
elementAfterBlock := block[len(block)-1] + 1
if x < elementAfterBlock {
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
index := sequential.SequentialSearch(block, x)
if index == -1 {
return -1 // wenn nicht gefunden
}
return index + i0 // NOTE: muss wegen Offset kompensieren
}
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
i0 = i1
i1 += m
}
return -1
}
/* ---------------------------------------------------------------- *
* ALGORITHM jump search - exponentiell
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl.
Annahmen:
- L sei aufsteigend sortiert.
- L enthält keine Duplikate.
Outputs: Position von x in L, sonst 1 wenn x nicht in L.
*/
func JumpSearchExponentiell(L []int, x int) int {
i0 := 0
i1 := 1
// ACHTUNG: dies ist eine while-Schleife ist golang:
for i0 < len(L) {
metrics.AddTimeCost()
if i1 > len(L) {
i1 = len(L)
}
block := L[i0:i1]
elementAfterBlock := block[len(block)-1] + 1
if x < elementAfterBlock {
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
index := sequential.SequentialSearch(block, x)
if index == -1 {
return -1 // wenn nicht gefunden
}
return index + i0 // NOTE: muss wegen Offset kompensieren
}
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
i0 = i1
i1 *= 2
}
return -1
}