97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
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
|
||
}
|