Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
| gf_informatik:suchen_und_sortieren_2024 [2024-01-22 14:01] – ↷ Links angepasst weil Seiten im Wiki verschoben wurden hof | gf_informatik:suchen_und_sortieren [2026-05-04 17:32] (aktuell) – hof | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| ====== Suchen und Sortieren ====== | ====== Suchen und Sortieren ====== | ||
| - | Weiter zu [[gf_informatik: | + | Weiter zu [[gf_informatik: |
| Direkt zu [[gf_informatik: | Direkt zu [[gf_informatik: | ||
| + | |||
| + | ++++Lernziele lineare und binäre Suche:| | ||
| + | * Ich kann erklären, wie die lineare Suche und wie die binäre Suche funktioniert. | ||
| + | * Ich kann die beiden Such-Algorithmen (linear und binär) miteinander vergleichen, | ||
| + | * Ich kann für eine gegebene Anzahl Einträge (Listen-Länge) die maximale Anzahl Abfragen für beide Such-Algorithmen berechnen. | ||
| + | * Ich kann eine Funktion '' | ||
| + | * Ich kann eine Funktion '' | ||
| + | * Ich kann Suchfunktionen (linear und binär) verwenden, um in mehreren zusammenpassenden Listen zusammengehörende Elemente zu finden – Beispiel: | ||
| + | ++++ | ||
| + | |||
| ==== Einführung ==== | ==== Einführung ==== | ||
| Zeile 22: | Zeile 32: | ||
| Der Sänger von _079_ will die Telefonnummer der Angebeteten unter allen möglichen Schweizer Mobilfunknummern (10-stellig) mit dem Präfix `079` herausfinden. Dafür probiert er sämtliche Nummern von `079 000 00 00` bis `079 999 99 99` durch, was natürlich ziemlich lange dauert... | Der Sänger von _079_ will die Telefonnummer der Angebeteten unter allen möglichen Schweizer Mobilfunknummern (10-stellig) mit dem Präfix `079` herausfinden. Dafür probiert er sämtliche Nummern von `079 000 00 00` bis `079 999 99 99` durch, was natürlich ziemlich lange dauert... | ||
| - | |||
| #### Aufgabe A1 - 079 | #### Aufgabe A1 - 079 | ||
| - | **Tipp**: [[https:// | + | **Tipp**: |
| 1. Wie viele Telefonnummern muss der Sänger von _079_ durchprobieren? | 1. Wie viele Telefonnummern muss der Sänger von _079_ durchprobieren? | ||
| Zeile 34: | Zeile 43: | ||
| 1. Wie lange dauerte die Suche, wenn wir nicht einmal die Vorwahl kennen würden (aber wüssten, dass alle Nummern mit `0` beginnen)? | 1. Wie lange dauerte die Suche, wenn wir nicht einmal die Vorwahl kennen würden (aber wüssten, dass alle Nummern mit `0` beginnen)? | ||
| - | < | + | < |
| ++++Lösung| | ++++Lösung| | ||
| Zeile 47: | Zeile 56: | ||
| === Algorithmus === | === Algorithmus === | ||
| - | Der einfachste Such-Algorithmus probiert alle Telefonnummern von der kleinsten zur grössten durch. Die Zeit für die Suche steigt proportional mit der Anzahl möglichen Nummern an - wir sagen auch, dass die Zeit **linear** mit der Grösse des Suchbereichs wächst, und sprechen von **Linearer Suche**. | + | Der einfachste Such-Algorithmus probiert alle Telefonnummern von der kleinsten zur grössten durch. Die Zeit für die Suche steigt |
| Würden wir statt _079_ nicht einmal die Vorwahl kennen, wäre die Suche nochmals zwei Dezimalstellen länger (wenn alle Telefonnummern mit 0 beginnen). Wir müssten also statt 6.5 sogar über 600 Jahre suchen. | Würden wir statt _079_ nicht einmal die Vorwahl kennen, wäre die Suche nochmals zwei Dezimalstellen länger (wenn alle Telefonnummern mit 0 beginnen). Wir müssten also statt 6.5 sogar über 600 Jahre suchen. | ||
| Zeile 56: | Zeile 65: | ||
| === Aufgabe A2: Lineare Suche in Python === | === Aufgabe A2: Lineare Suche in Python === | ||
| - | Betrachte folgenden Datensatz mit Namen und Telefonnummern. Wir haben zwei parallele Listen, die erste mit Namen, die zweite mit den dazugehörigen Telefonnummern. | + | Betrachte folgenden Datensatz mit Namen und Telefonnummern. Wir haben zwei parallele Listen, die erste mit Namen, die zweite mit den dazugehörigen Telefonnummern. Am gleichen Index ist in der ersten Liste der Name, in der zweiten die Telefonnummer gespeichert. |
| - | Zum Beispiel | + | Zum Beispiel |
| - | <code python lineare_suche.py> | + | <bottom-exercise showsolution id=" |
| + | < | ||
| names = [' | names = [' | ||
| ' | ' | ||
| ' | ' | ||
| ' | ' | ||
| - | numbers = [' | + | numbers = [' |
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | </ | ||
| + | < | ||
| + | assert linear_search(names, | ||
| + | assert linear_search([1, | ||
| + | </ | ||
| + | < | ||
| + | names = [' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | numbers = [' | ||
| ' | ' | ||
| ' | ' | ||
| ' | ' | ||
| - | </ | ||
| - | - Schreibe eine Python-Funktion `linear_search(l, | ||
| - | - Test: Der Funktionsaufruf `print(linear_search(names, | ||
| - | - Nun wissen wir, dass die gesuchte Dame `Lyanna` (_die Geheimnisvolle_) heisst. Nutze nun diese Funktion, um die Telefonnummer von ' | ||
| - | **Achtung: | ||
| - | |||
| - | ++++Tipps (zuerst ohne Tipps versuchen!)| | ||
| - | - Gehe IN der Funktion die Liste alle möglichen Indices (Positionen) durch. | ||
| - | - Vergleiche das Element an jedem Index mit dem gesuchten Wert. | ||
| - | - Wenn es gleich ist: Gebe den Index zurück. | ||
| - | - Ausserhalb der Funktion: Lese nun aus der **anderen** Liste das Element mit dem eben ermittelten Index aus. | ||
| - | ++++ | ||
| - | |||
| - | |||
| - | <nodisp 1> | ||
| - | ++++Lösung| | ||
| - | <code python> | ||
| def linear_search(l, | def linear_search(l, | ||
| for i in range(len(l)): | for i in range(len(l)): | ||
| Zeile 95: | Zeile 102: | ||
| index = linear_search(names, | index = linear_search(names, | ||
| print(numbers[index]) | print(numbers[index]) | ||
| - | </code> | + | </template> |
| + | </ | ||
| + | |||
| + | - Schreibe eine Python-Funktion `linear_search(l, | ||
| + | - Test: Der Funktionsaufruf `print(linear_search(names, | ||
| + | - Nun wissen wir, dass die gesuchte Dame `Lyanna` (_die Geheimnisvolle_) heisst. Nutze nun diese Funktion, um die Telefonnummer von ' | ||
| + | |||
| + | **Achtung: | ||
| + | |||
| + | ++++Tipps (zuerst ohne Tipps versuchen!)| | ||
| + | - Gehe IN der Funktion die Liste `l` alle möglichen Indices (Positionen) durch ([[gf_informatik: | ||
| + | - Vergleiche das Element an jedem Index (also `l[index]`) mit dem gesuchten Wert `v`. | ||
| + | - Wenn es gleich ist: Gib den Index zurück. | ||
| + | - Ausserhalb der Funktion: Lese nun aus der **anderen** Liste das Element mit dem eben ermittelten Index aus. | ||
| ++++ | ++++ | ||
| - | </ | ||
| === Aufgabe A3: Zäh Millione Kombinatione === | === Aufgabe A3: Zäh Millione Kombinatione === | ||
| + | < | ||
| + | <div slot=" | ||
| Für das kleine Telefonbuch oben ist es nicht so wichtig, wie schnell der Such-Algorithmus ist. Was aber, wenn wir wirklich alle 10 Millionen Kombinationen durchprobieren? | Für das kleine Telefonbuch oben ist es nicht so wichtig, wie schnell der Such-Algorithmus ist. Was aber, wenn wir wirklich alle 10 Millionen Kombinationen durchprobieren? | ||
| - | Lade die Datei [[https:// | + | < |
| - | Du kannst das Telefonbuch wie folgt importieren und den Namen für eine Telefonnummer herausfinden. Der Code muss im gleichen Ordner wie `null79.py` abgespeichert werden | + | < |
| - | + | </ | |
| - | <code python> | + | <template data-type=" |
| from null79 import names, numbers | from null79 import names, numbers | ||
| - | index = 42 | + | index = 42 # TODO: Suche den Index von Lyanna! |
| name = names[index] | name = names[index] | ||
| - | telnr = numbers[index] | + | tel = numbers[index] |
| - | print("Die Telefonnummer von " + name + " | + | print(f'Die Telefonnummer von {name} ist {tel}') |
| - | </code> | + | </template> |
| - | + | <template data-type=" | |
| - | Verwende deine `linear_search()` Funktion, um die richtige Telefonnummer von Lyanna herauszufinden. Wie lange dauert die Suche? | + | |
| - | + | ||
| - | <nodisp 2> | + | |
| - | ++++Lösung mit Code| | + | |
| - | <code python Aufgabe A3.py> | + | |
| from null79 import names, numbers | from null79 import names, numbers | ||
| Zeile 129: | Zeile 145: | ||
| name = ' | name = ' | ||
| - | idx = linear_search(names, | + | index = linear_search(names, |
| - | if idx is None: | + | if index == None: |
| print(" | print(" | ||
| else: | else: | ||
| - | tel = numbers[idx] | + | tel = numbers[index] |
| - | print("Die Telefonnummer von " + name + " | + | print(f'Die Telefonnummer von {name} ist {tel}') |
| print(" | print(" | ||
| - | print(" | + | print(" |
| - | print(" | + | print(" |
| - | </code> | + | </template> |
| + | </ | ||
| + | |||
| + | Oben ist die Datei `null79.py` bereits im gleichen Ordner hinterlegt - wenn du den Code in TigerJython oder VisualStudioCode ausführst, muss die Datei ebenfalls dort abgespeichert werden. | ||
| + | |||
| + | ++++ Mit TigerPython / VisualStudioCode :| | ||
| + | Mit [[https:// | ||
| + | Für VisualStudioCode: | ||
| + | |||
| + | Lade die Datei [[https:// | ||
| ++++ | ++++ | ||
| - | </ | ||
| === Aufgabe A4: Maximal sächsehalb Jahr lang === | === Aufgabe A4: Maximal sächsehalb Jahr lang === | ||
| Wir möchten genau wissen, wie lange die Suche dauert, auch wenn es hoffentlich nicht 6.5 Jahre sind. | Wir möchten genau wissen, wie lange die Suche dauert, auch wenn es hoffentlich nicht 6.5 Jahre sind. | ||
| - | Um in Python die Zeit zu stoppen, kannst du das `time` Modul verwenden. Wie lange dauert die Suche für die `Lyanna`? Wie lange für `Annina`? Weshalb der Unterschied? | + | Um in Python die Zeit zu stoppen, kannst du das `time` Modul verwenden. Wie lange dauert die Suche für die `Lyanna`? Wie lange für `Annina` oder `Zoraya`? Weshalb der Unterschied? |
| - | <code python> | + | <bottom-exercise id=" |
| + | < | ||
| import time | import time | ||
| + | # Startzeitpunkt bestimmen | ||
| start = time.time() | start = time.time() | ||
| - | # do something | + | |
| + | # TODO: Hier muss die Suche passieren | ||
| + | |||
| + | # Endzeitpunkt bestimmen und Differenz zum Start berechnen | ||
| elapsed = time.time() - start | elapsed = time.time() - start | ||
| - | print("do something took {0}s" | + | # Ausgabe - das ': |
| - | </code> | + | print(f' |
| - | + | </template> | |
| - | <nodisp 2> | + | <template data-type=" |
| - | ++++Lösung| | + | |
| - | <code python time_algos.py> | + | |
| from null79 import names, numbers | from null79 import names, numbers | ||
| import time | import time | ||
| + | |||
| def linear_search(l, | def linear_search(l, | ||
| for i in range(len(l)): | for i in range(len(l)): | ||
| Zeile 167: | Zeile 194: | ||
| return i | return i | ||
| return None | return None | ||
| + | |||
| def stopwatch(name): | def stopwatch(name): | ||
| start = time.time() | start = time.time() | ||
| index = linear_search(names, | index = linear_search(names, | ||
| elapsed = time.time() - start | elapsed = time.time() - start | ||
| - | print("Lineare Suche für {0} dauerte {1:.1f}s" | + | print(f'Lineare Suche für {name} dauerte {elapsed:.1f}s') |
| + | |||
| + | stopwatch(' | ||
| + | stopwatch(' | ||
| + | stopwatch(' | ||
| + | </ | ||
| + | </ | ||
| - | stopwatch(' | ||
| - | stopwatch(' | ||
| - | </ | ||
| - | ++++ | ||
| - | </ | ||
| === Aufgabe A5: Umgekehrte Suche === | === Aufgabe A5: Umgekehrte Suche === | ||
| Zeile 187: | Zeile 215: | ||
| ++++ | ++++ | ||
| - | < | + | < |
| ++++Code| | ++++Code| | ||
| - | <code python> | + | <bottom-editor timeout=" |
| idx = linear_search(numbers, | idx = linear_search(numbers, | ||
| print(names[idx]) | print(names[idx]) | ||
| - | </code> | + | </bottom-editor> |
| ++++ | ++++ | ||
| </ | </ | ||
| - | === Aufgabe | + | === Aufgabe |
| Wenn wir nach einem Namen suchen, der gar nicht in der Liste vorkommt, z.B. `Alaska`, so dauert die Suche lange, weil die ganze Liste durchsucht wird. | Wenn wir nach einem Namen suchen, der gar nicht in der Liste vorkommt, z.B. `Alaska`, so dauert die Suche lange, weil die ganze Liste durchsucht wird. | ||
| Zeile 202: | Zeile 230: | ||
| Nun sind die Namen in `null79.names` *alphabetisch sortiert*. Sobald wir einen Namen antreffen, der alphabetisch nach dem gesuchten Wert liegt, können wir die Suche abbrechen. Strings können in Python mit den `>` und `<` Operatoren verglichen werden: | Nun sind die Namen in `null79.names` *alphabetisch sortiert*. Sobald wir einen Namen antreffen, der alphabetisch nach dem gesuchten Wert liegt, können wir die Suche abbrechen. Strings können in Python mit den `>` und `<` Operatoren verglichen werden: | ||
| - | <code python> | + | <bottom-editor> |
| s1 = ' | s1 = ' | ||
| s2 = ' | s2 = ' | ||
| Zeile 209: | Zeile 237: | ||
| else: | else: | ||
| print(s1 + ' liegt im Alphabet nach ' + s2) | print(s1 + ' liegt im Alphabet nach ' + s2) | ||
| - | </code> | + | </bottom-editor> |
| Erweitere deine Funktion `linear_search()` wie folgt: | Erweitere deine Funktion `linear_search()` wie folgt: | ||
| Zeile 216: | Zeile 244: | ||
| * Ist die Liste sortiert, soll die Suche abbrechen, wenn wir im Alphabet bereits weiter sind als der gesuchte Wert. | * Ist die Liste sortiert, soll die Suche abbrechen, wenn wir im Alphabet bereits weiter sind als der gesuchte Wert. | ||
| - | < | + | < |
| ++++Lösung| | ++++Lösung| | ||
| <code python> | <code python> | ||
| Zeile 230: | Zeile 258: | ||
| </ | </ | ||
| - | === Aufgabe | + | === Aufgabe |
| Hast du eine Idee für einen besseren, sprich effizienteren Suchalgorithmus einer bereits sortierten Liste? Bespreche mit der Lehrperson und implementiere danach in Python. | Hast du eine Idee für einen besseren, sprich effizienteren Suchalgorithmus einer bereits sortierten Liste? Bespreche mit der Lehrperson und implementiere danach in Python. | ||
| Zeile 237: | Zeile 265: | ||
| ---- | ---- | ||
| - | Weiter zu [[gf_informatik: | + | Weiter zu [[gf_informatik: |