2021-11-01 19:58:55 +01:00
|
|
|
|
package jump
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
|
|
|
* IMPORTS
|
|
|
|
|
* ---------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
|
|
"ads/internal/algorithms/search/sequential"
|
|
|
|
|
"ads/internal/core/logging"
|
|
|
|
|
"ads/internal/core/metrics"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
|
|
|
* GLOBAL VARIABLES/CONSTANTS
|
|
|
|
|
* ---------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
|
|
|
* ALGORITHM jump search
|
|
|
|
|
* ---------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
|
|
|
|
|
|
|
|
|
Annahmen:
|
|
|
|
|
- L sei aufsteigend sortiert.
|
2021-11-02 13:18:11 +01:00
|
|
|
|
- Idealerweise: L enthält keine Duplikate.
|
|
|
|
|
- Idealerweise: Abstände zw. Elementen nicht uniform.
|
2021-11-01 19:58:55 +01:00
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
block := L[i0:i1]
|
|
|
|
|
elementAfterBlock := block[len(block)-1] + 1
|
|
|
|
|
if x < elementAfterBlock {
|
|
|
|
|
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
|
|
|
|
|
index := sequential.SequentialSearch(block, x)
|
|
|
|
|
if index >= 0 {
|
|
|
|
|
index += i0 // NOTE: muss wegen Offset kompensieren
|
|
|
|
|
}
|
|
|
|
|
return index
|
|
|
|
|
}
|
|
|
|
|
logging.LogDebug(fmt.Sprintf("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()
|
|
|
|
|
block := L[i0:i1]
|
|
|
|
|
elementAfterBlock := block[len(block)-1] + 1
|
|
|
|
|
if x < elementAfterBlock {
|
|
|
|
|
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
|
|
|
|
|
index := sequential.SequentialSearch(block, x)
|
|
|
|
|
if index >= 0 {
|
|
|
|
|
index += i0 // NOTE: muss wegen Offset kompensieren
|
|
|
|
|
}
|
|
|
|
|
return index
|
|
|
|
|
}
|
|
|
|
|
logging.LogDebug(fmt.Sprintf("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1))
|
|
|
|
|
i0 = i1
|
|
|
|
|
i1 *= 2
|
|
|
|
|
}
|
|
|
|
|
return -1
|
|
|
|
|
}
|