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. - 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() 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 }