2021-10-23 13:20:37 +02:00
|
|
|
|
#!/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;
|
2021-10-24 12:28:37 +02:00
|
|
|
|
from code.algorithms.methods import *;
|
2021-10-23 13:20:37 +02:00
|
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
# GLOBAL VARIABLES/CONSTANTS
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
2021-10-24 12:28:37 +02:00
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
# CHECKS
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
def preChecks(L: List[int], **_):
|
|
|
|
|
assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!';
|
2021-10-24 20:12:05 +02:00
|
|
|
|
assert L == sorted(list(set(L))), 'Ungültiger Input: L darf keine Duplikate enthalten!';
|
2021-10-24 12:28:37 +02:00
|
|
|
|
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;
|
|
|
|
|
|
2021-10-23 13:20:37 +02:00
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
# ALGORITHM jump search
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2021-10-24 12:28:37 +02:00
|
|
|
|
@algorithmInfos(name='Sprungsuche', outputnames='index', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
|
2021-10-23 13:20:37 +02:00
|
|
|
|
def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
|
|
|
|
|
'''
|
2021-10-24 23:34:07 +02:00
|
|
|
|
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
2021-10-24 13:18:39 +02:00
|
|
|
|
|
2021-10-23 13:20:37 +02:00
|
|
|
|
Annahmen:
|
2021-10-24 13:18:39 +02:00
|
|
|
|
- L sei aufsteigend sortiert.
|
|
|
|
|
- L enthält keine Duplikate.
|
|
|
|
|
|
2021-10-23 13:20:37 +02:00
|
|
|
|
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:
|
2021-10-24 23:34:07 +02:00
|
|
|
|
logDebug('Element muss sich im Block [{i0}, {i1}) befinden.'.format(i0 = i*m, i1 = (i+1)*m));
|
2021-10-24 12:28:37 +02:00
|
|
|
|
index = SequentialSearch(L=block, x=x);
|
2021-10-25 11:27:33 +02:00
|
|
|
|
if index >= 0:
|
|
|
|
|
index += offset; # NOTE: muss wegen Offset kompensieren
|
|
|
|
|
return index;
|
2021-10-24 23:34:07 +02:00
|
|
|
|
logDebug('Element befindet sich nicht im im Block [{i0}, {i1}) befinden.'.format(i0 = i*m, i1 = (i+1)*m));
|
2021-10-23 13:20:37 +02:00
|
|
|
|
i += 1;
|
|
|
|
|
return -1;
|
2021-10-24 23:34:07 +02:00
|
|
|
|
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
# ALGORITHM jump search - exponentiell
|
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
@algorithmInfos(name='Sprungsuche (exponentiell)', outputnames='index', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
|
|
|
|
|
def JumpSearchExponentiell(L: List[int], x: int) -> int:
|
|
|
|
|
'''
|
|
|
|
|
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.
|
|
|
|
|
'''
|
|
|
|
|
i0 = 0;
|
|
|
|
|
i1 = 1;
|
|
|
|
|
while i0 < len(L):
|
|
|
|
|
AddToCounter();
|
|
|
|
|
block = L[i0:i1];
|
|
|
|
|
elementAfterBlock = block[-1] + 1;
|
|
|
|
|
if x < elementAfterBlock:
|
|
|
|
|
logDebug('Element muss sich im Block [{i0}, {i1}) befinden.'.format(i0 = i0, i1 = i1));
|
|
|
|
|
index = SequentialSearch(L=block, x=x);
|
2021-10-25 11:27:33 +02:00
|
|
|
|
if index >= 0:
|
|
|
|
|
index += i0; # NOTE: muss wegen Offset kompensieren
|
|
|
|
|
return index;
|
2021-10-24 23:34:07 +02:00
|
|
|
|
logDebug('Element befindet sich nicht im Block [{i0}, {i1}) befinden.'.format(i0 = i0, i1 = i1));
|
|
|
|
|
i0 = i1;
|
|
|
|
|
i1 *= 2;
|
|
|
|
|
return -1;
|