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 }