ads1_2021/code/golang/internal/algorithms/search/interpol/interpol.go

70 lines
2.0 KiB
Go
Raw Normal View History

package interpol
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"math"
"ads/internal/core/logging"
"ads/internal/core/metrics"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* ALGORITHM interpolation
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl.
Annahme: L sei aufsteigend sortiert.
Outputs: Position von x in L, sonst 1 wenn x nicht in L.
*/
func InterpolationSearch(L []int, x int, u int, v int) int {
if len(L) == 0 {
logging.LogDebug(fmt.Sprintf("Liste L leer, also x nicht in L"))
return -1
} else if !(L[u] <= x && x <= L[v]) {
logging.LogDebug(fmt.Sprintf("x liegt außerhalb der Grenzen von L"))
return -1
}
metrics.AddTimeCost()
p := getSuchposition(L, x, u, v)
logging.LogDebug(fmt.Sprintf("Interpolante von x in (u, v)=(%[1]v, %[2]v) ist p = %[3]v.", u, v, p))
if L[p] == x {
logging.LogDebug(fmt.Sprintf("x in Position p gefunden"))
return p
} else if x < L[p] {
logging.LogDebug(fmt.Sprintf("Suche in linker Hälfte fortsetzen."))
return InterpolationSearch(L, x, u, p-1)
} else { // } else if x > L[p] {
logging.LogDebug(fmt.Sprintf("Suche in rechter Hälfte fortsetzen."))
return InterpolationSearch(L, x, p+1, v)
}
}
/* ---------------------------------------------------------------- *
* ALGORITHM interpolation
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen.
*/
func getSuchposition(L []int, x int, u int, v int) int {
metrics.AddTimeCost()
r := float64(x-L[u]) / float64(L[v]-L[u])
p := int(math.Floor(float64(u) + r*float64(v-u)))
return p
}