#!/usr/bin/env python3 # -*- coding: utf-8 -*- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # IMPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from local.maths import *; from local.typing import *; from code.core.log import *; from code.algorithms.search.sequential import SequentialSearch; from code.algorithms.methods import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # GLOBAL VARIABLES/CONSTANTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # CHECKS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def preChecks(L: List[int], **_): assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!'; assert L == sorted(list(set(L))), 'Ungültiger Input: L darf keine Duplikate enthalten!'; return; def postChecks(L: List[int], x: int, index: int, **_): value = L[index] if index >= 0 else None; assert value == x, 'Der Algorithmus hat versagt.'; return; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ALGORITHM jump search # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @algorithmInfos(name='Sprungsuche', outputnames='index', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) def JumpSearchLinear(L: List[int], x: int, m: int) -> int: ''' Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval. Annahmen: - L sei aufsteigend sortiert. - L enthält keine Duplikate. Outputs: Position von x in L, sonst −1 wenn x nicht in L. ''' i = 0; while i*m < len(L): AddToCounter(); offset = i*m; block = L[offset:][:m]; elementAfterBlock = block[-1] + 1; if x < elementAfterBlock: logDebug('Element muss sich im Block {} befinden.'.format(i)); index = SequentialSearch(L=block, x=x); return offset + index; # NOTE: muss wegen Offset kompensieren logDebug('Element befindet sich nicht im Block {}.'.format(i)); i += 1; return -1;