[12] Metody projektowania algorytmów (dziel i rządź, programowanie dynamiczne i algorytmy zachłanne).

Podobne dokumenty
Sortowanie przez wstawianie Insertion Sort

Strategia "dziel i zwyciężaj"

Sortowanie przez scalanie

Algorytmy sortujące i wyszukujące

Egzamin, AISDI, I termin, 18 czerwca 2015 r.

EGZAMIN - Wersja A. ALGORYTMY I STRUKTURY DANYCH Lisek89 opracowanie kartki od Pani dr E. Koszelew

Sortowanie. LABORKA Piotr Ciskowski

(3 kwiecień 2014) Marika Pankowska Kamila Pietrzak

Sortowanie - wybrane algorytmy

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Sortowanie. Bartman Jacek Algorytmy i struktury

Struktury Danych i Złożoność Obliczeniowa

Programowanie w VB Proste algorytmy sortowania

Wstęp do programowania

Analiza algorytmów zadania podstawowe

Algorytmy i Struktury Danych.

Zaawansowane algorytmy i struktury danych

Anna Sobocińska Sylwia Piwońska

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Podstawowe algorytmy i ich implementacje w C. Wykład 9

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

PODSTAWY INFORMATYKI wykład 5.

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

Sortowanie Shella Shell Sort

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne

Laboratorium nr 7 Sortowanie

Porównanie Heap Sort, Counting Sort, Shell Sort, Bubble Sort. Porównanie sortowao: HS, CS, Shs, BS

Schemat programowania dynamicznego (ang. dynamic programming)

Algorytmy przeszukiwania wzorca

Efektywna metoda sortowania sortowanie przez scalanie

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze,

Literatura. 1) Pojęcia: złożoność czasowa, rząd funkcji. Aby wyznaczyć pesymistyczną złożoność czasową algorytmu należy:

Programowanie dynamiczne i algorytmy zachłanne

Algorytmy i struktury danych. Wykład 4 Tablice nieporządkowane i uporządkowane

INFORMATYKA SORTOWANIE DANYCH.

Programowanie dynamiczne cz. 2

Algorytmy i str ruktury danych. Metody algorytmiczne. Bartman Jacek

Algorytmy sortujące. Sortowanie bąbelkowe

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i struktury danych

znalezienia elementu w zbiorze, gdy w nim jest; dołączenia nowego elementu w odpowiednie miejsce, aby zbiór pozostał nadal uporządkowany.

Złożoność algorytmów. Wstęp do Informatyki

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Algorytmy i struktury danych Laboratorium 7. 2 Drzewa poszukiwań binarnych

Drzewa poszukiwań binarnych

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Sortowanie bąbelkowe

Sortowanie bąbelkowe - wersja nr 1 Bubble Sort

Temat 7. Najlżejsze i najcięższe algorytmy sortowania

Jeszcze o algorytmach

Złożoność obliczeniowa zadania, zestaw 2

Algorytmy i struktury danych Sortowanie IS/IO, WIMiIP

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Metodyki i Techniki Programowania 2

Zadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Luty 2001 Algorytmy (4) 2000/2001

Zasady analizy algorytmów

Podstawy Informatyki. Sprawność algorytmów

Luty 2001 Algorytmy (7) 2000/2001

Algorytmy sortujące 1

Algorytm selekcji Hoare a. Łukasz Miemus

Struktury danych i złożoność obliczeniowa Wykład 2. Prof. dr hab. inż. Jan Magott

Algorytmy przeszukiwania

Teoretyczne podstawy informatyki

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy i struktury danych

Haszowanie (adresowanie rozpraszające, mieszające)

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

Algorytmy i Struktury Danych, 2. ćwiczenia

Matematyczne Podstawy Informatyki

Metody numeryczne w przykładach

Algorytmy i Struktury Danych.

Wyszukiwanie binarne

Algorytmy decyzyjne będące alternatywą dla sieci neuronowych

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 9. Karol Tarnowski A-1 p.

Techniki konstruowania algorytmów. Metoda dziel i zwyciężaj

Podstawy Informatyki. Metody dostępu do danych

Struktury danych i złożoność obliczeniowa Wykład 7. Prof. dr hab. inż. Jan Magott

Temat: Algorytmy wyszukiwania wzorca w tekście

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego.

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Podstawy Programowania 1 Sortowanie tablic jednowymiarowych. Plan. Sortowanie. Sortowanie Rodzaje sortowania. Notatki. Notatki. Notatki.

Algorytmy wyznaczania centralności w sieci Szymon Szylko

wstęp do informatyki i programowania część testowa (25 pyt. / 60 min.)

Algorytmy i struktury danych

B.B. 2. Sumowanie rozpoczynamy od ostatniej kolumny. Sumujemy cyfry w kolumnie zgodnie z podaną tabelką zapisując wynik pod kreską:

PODSTAWY INFORMATYKI wykład 10.

Wykład 3. Metoda dziel i zwyciężaj

Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa

Sortowanie zewnętrzne

Tablice z haszowaniem

Algorytmy sztucznej inteligencji

Informatyka A. Algorytmy

Systemy liczbowe używane w technice komputerowej

Problemy porządkowe zadania

Transkrypt:

[12] Metody projektowania algorytmów (dziel i rządź, programowanie dynamiczne i algorytmy zachłanne). Tworzenie projektów informatycznych opiera się w dużej mierze na formułowaniu i implementacji algorytmów, które mają za zadanie właściwe przetworzenie danych i rozwiązanie postawionych przed nami problemów. Algorytmy można sklasyfikować na kilka różnych sposobów,ale wśród nich najważniejszy jest podział ze względu na techniki ich konstruowania. Są pewne techniki tworzenia algorytmów, których zastosowanie prowadzi do efektywniejszego rozwiązywania problemów niż za pomocą algorytmów konstruowanych w sposób spontaniczny. Przedstawimy kilka z nich: Dziel i rządź prowadzi nierzadko do bardzo efektywnych rozwiązań polega na rekurencyjnym dzieleniu problemu na dwa mniejsze podproblemy dzielenie ma miejsce tak długo aż podproblemy stają się proste do bezpośredniego rozwiązania zwykle podproblemy są mniejszymi kopiami podproblemu z którego powstały oficjalnie pierwszy raz zastosowano tę metodą w 1960 roku Algorytm sprawdza czy w podanej, posortowanej tablicy znajduje się element o danej wartości. tablica jest dzielona na coraz mniejsze elementy (na pół) jako potencjalny element do wyszukania typuje się element środkowy w zależności od wartości elementu środkowego, kontynuuje się przeszukiwanie odpowiedniej części tablicy (zawężenie przedziału) podział kończy się gdy znajdziemy szukany element lub gdy przedział osiągnie długość 0

Dla tablicy 1.000.000 elementów nie musimy sprawdzać każdego z nich - wystarczy tylko 20 kroków.

Programowanie dynamiczne stosowane głównie do rozwiązywanie problemów optymalizacyjnych alternatywa dla pewnych zagadnień rozwiązywanych metodami zachłannymi W odniesieniu do programowania opartego o dziel i zwyciężaj : Jeżeli podproblemy, na które został podzielony problem główny, nie są niezależne to w różnych podproblemach wykonywane są wiele razy te same obliczenia, warto jest wtedy zastosować ulepszenie tej metody jakim jest zastosowanie programowania dynamicznego Programowanie dynamiczne zasady wyniki poszczególnych obliczeń są zapamiętywane w pomocniczej tablicy tablica ta jest wykorzystywana w kolejnych krokach eliminuje to konieczność wielokrotnego powtarzania tych samych obliczeń Dla każdego podproblemu obliczenia są zatem wykonane tylko raz, a ich wynik jest zapamiętywany Programowanie dynamiczne zastosowanie automatach do kawy przy wydawaniu reszty w taki sposób, by monet było jak najmniej. algorytm Floyda-Warshalla (najkrótsze ścieżki między wszystkimi wierzchołkami w grafie)

Algorytmy zachłanne algorytm w każdym kroku dokonuje wyboru będącego na daną chwilę tym najlepszym (najbliższym końcowemu rozwiązaniu) podejmuje decyzje optymalne tylko lokalnie kontynuuje działania wynikające z poprzednich decyzji podejście często okazuje się nieoptymalne Algorytmy zachłanne przykład Algorytm Kruskala (MST) Algorytm Dijkstry (najkrótsza ścieżka w grafie o nieujemnych wagach)

[13] Elementarne i nieelementarne metody sortowania. Przyjęło się mówić że elementarne metody sortowania to te których czas działania jest równy O(n 2 ). Zaliczają się do nich następujące algorytmy sortowania : 1.1. Sortowanie przez selekcję(selection sort) Jest nieadaptacyjne, wewnętrzne i stabilne oraz nie wymaga dodatkowej pamięci. Jego czas działania jest określony z góry O(n 2 ). Sortowanie to jest najlepsze, spośród innych elementarnych, do sortowania elementów o małych kluczach i dużych polach, ponieważ wykonuje najmniej wstawień. W pierwszym przebiegu algorytm znajduje najmniejszy element w tablicy i zamienia go z pierwszym. W drugim przebiegu algorytm znajduje najmniejszy element w podtablicy [2..r] i zamienia go z drugim. I tak aż do zamiany r-tego elementu z r-1 elementem. 1.2. Przez wstawianie Sortowanie przez wstawienie (insertion sort) to algorytm, którego czas działania wynosi O(n 2 ). Jest on skuteczny dla małej ilości danych. Jest to jeden z prostszych i jeden z bardziej znanych algorytmów sortowania. Jest on stabilny i nie wymaga dodatkowej pamięci (działa w miejscu). Najważniejszą operacją w opisywanym algorytmie sortowania jest wstawianie wybranego elementu na listę uporządkowaną. Zasady są następujące: 1) Na początku sortowania lista uporządkowana zawiera tylko jeden, ostatni element zbioru. Jednoelementowa lista jest zawsze uporządkowana. 2) Ze zbioru zawsze wybieramy element leżący tuż przed listą uporządkowaną. Element ten zapamiętujemy w zewnętrznej zmiennej. Miejsce, które zajmował, możemy potraktować jak puste. 3) Wybrany element porównujemy z kolejnymi elementami listy uporządkowanej. 4) Jeśli natrafimy na koniec listy, element wybrany wstawiamy na puste miejsce - lista rozrasta się o nowy element. 5) Jeśli element listy jest większy od wybranego, to element wybrany wstawiamy na puste miejsce - lista rozrasta się o nowy element. 6) Jeśli element listy nie jest większy od wybranego, to element listy przesuwamy na puste miejsce. Dzięki tej operacji puste miejsce wędruje na liście przed kolejny element. Kontynuujemy porównywanie, aż wystąpi sytuacja z punktu 4 lub 5. 1.3. Sortowanie bąbelkowe Jest to algorytm nieadaptacyjny, wewnętrzny i stabilny oraz nie wymagający dodatkowej pamięci. Jego czas działania jest określony z góry przez wynosi O(n 2 ) algorytm wykonuje w najgorszym i średnim przypadku około porównao i zamian. Zasada działania opiera się na cyklicznym porównywaniu par sąsiadujących elementów i zamianie ich kolejności w przypadku niespełnienia kryterium porządkowego zbioru. Operację tę wykonujemy dotąd, aż cały zbiór zostanie posortowany.

Lista kroków 1: Dla j = 1,2,...,n - 1: wykonuj Krok 2 2: Dla i = 1,2,...,n - 1: jeśli d[i] > d[i + 1], to d[i] d[i + 1] 3: Zakończ gdzie: n- liczba elementów w sortowanym zbiorze d[ ]- zbiór n- elementowy, który będzie sortowany. Elementy zbioru mają indeksy od 1 do n. Do nieelementarnych algorytmów sortowania zaliczamy : 1.4. Sortowanie szybkie(quicksort) Algorytm sortowania szybkiego opiera się na strategii "dziel i zwyciężaj" (ang. divide and conquer), którą możemy krótko scharakteryzować w trzech punktach: DZIEL - problem główny zostaje podzielony na podproblemy ZWYCIĘŻAJ - znajdujemy rozwiązanie podproblemów POŁĄCZ - rozwiązania podproblemów zostają połączone w rozwiązanie problemu głównego Idea sortowania szybkiego jest następująca: DZIEL: najpierw sortowany zbiór dzielimy na dwie części w taki sposób, aby wszystkie elementy leżące w pierwszej części (zwanej lewą partycją) były mniejsze lub równe od wszystkich elementów drugiej części zbioru (zwanej prawą partycją). ZWYCIĘŻAJ : każdą z partycji sortujemy rekurencyjnie tym samym algorytmem. POŁĄCZ : połączenie tych dwóch partycji w jeden zbiór daje w wyniku zbiór posortowany. W przypadku typowym algorytm ten jest najszybszym algorytmem sortującym z klasy złożoności obliczeniowej O(n log n) - stąd pochodzi jego popularność w zastosowaniach. Musimy jednak pamiętać, iż w pewnych sytuacjach (zależnych od sposobu wyboru piwotu oraz niekorzystnego ułożenia danych wejściowych) klasa złożoności obliczeniowej tego algorytmu może się degradować do O(n 2 ), co więcej, poziom wywołao rekurencyjnych może spowodować przepełnienie stosu i zablokowanie komputera. Z tych powodów algorytmu sortowania szybkiego nie można stosować bezmyślnie w każdej sytuacji tylko dlatego, iż jest uważany za jeden z najszybszych algorytmów sortujących - zawsze należy przeprowadzić analizę możliwych danych wejściowych właśnie pod kątem przypadku niekorzystnego. 1.5. Sortowanie przez łączenie(scalanie) Jest nieadaptacyjne, zewnętrzne i stabilne oraz wymaga dodatkowej pamięci proporcjonalnej do n. Jego czas działania jest określony z góry przez O(n log(n)). Sortowanie przez scalanie jest nieadaptacyjne, ale jest za to relatywnie szybkie niezależnie od układu danych. W związku z tym algorytm ten stosuje się, gdy jednocześnie ważna jest szybkość algorytmu i nie akceptowana jest wydajność najgorszego przypadku innych sortowao, a do tego możemy jeszcze pozwolić sobie na poświęcenie trochę pamięci na operację sortownia. Ideą działania algorytmu jest dzielenie zbioru danych na mniejsze zbiory, aż do uzyskania n zbiorów jednoelementowych, które same z siebie są posortowane, następnie zbiory te są

łączone w coraz większe zbiory posortowane, aż do uzyskania jednego, posortowanego zbioru nelementowego. Etap dzielenia nie jest skomplikowany, dzielenie następuje bez sprawdzania jakichkolwiek warunków. Dzięki temu, w przeciwieostwie do algorytmu sortowania szybkiego, następuje pełne rozwinięcie wszystkich gałęzi drzewa. Z kolei łączenie zbiorów posortowanych wymaga odpowiedniego wybierania poszczególnych elementów z łączonych zbiorów z uwzględnieniem faktu, że wielkość zbioru nie musi być równa (parzysta i nieparzysta ilość elementów), oraz tego, iż wybieranie elementów z poszczególnych zbiorów nie musi następować naprzemiennie, przez co jeden zbiór może osiągać swój koniec wcześniej niż drugi. Robi sie to w następujący sposób. Kopiujemy zawartość zbioru głównego do struktury pomocniczej. Następnie, operując wyłącznie na kopii, ustawiamy wskaźniki na początki kolejnych zbiorów i porównujemy wskazywane wartości. Mniejszą wartość wpisujemy do zbioru głównego i przesuwamy odpowiedni wskaźnik o 1 i czynności powtarzamy, aż do momentu, gdy jeden ze wskaźników osiągnie koniec zbioru. Wówczas mamy do rozpatrzenia dwa przypadki, gdy zbiór 1 osiągnął koniec i gdy zbiór 2 osiągnął koniec. W przypadku pierwszym nie będzie problemu, elementy w zbiorze głównym są już posortowane i ułożone na właściwych miejscach. W przypadku drugim trzeba skopiować pozostałe elementy zbioru pierwszego po kolei na koniec. Po zakooczeniu wszystkich operacji otrzymujemy posortowany zbiór główny. 1.6. Sortowanie pozycyjne Algorytm sortowania porządkujący stabilnie ciągi wartości (liczb, słów) względem konkretnych cyfr, znaków itp, kolejno od najmniej znaczących do najbardziej znaczących pozycji. Złożoność obliczeniowa jest równa O(d(n + k)), gdzie k to liczba różnych cyfr, a d liczba cyfr w kluczach. Wymaga O(n + k) dodatkowej pamięci. Pozycją (ang. radix) nazywamy miejsce cyfry w zapisie liczby.. Algorytm sortujący musi być stabilny, tzn. nie może zmieniać kolejności elementów równych, w przeciwnym razie efekty poprzednich sortowao zostaną utracone. Sortowanie pozycyjne możemy także zastosować do sortowania rekordów baz danych. Na przykład chcemy posortować książkę telefoniczną według nazwisk, a w razie gdyby się one powtarzały to według imion, a w przypadku identyczności imion i nazwisk według numeru telefonu. Aby otrzymać taki wynik powinniśmy tą książkę telefoniczną posortować najpierw według numeru telefonu, potem według imion, a na koocu według nazwisk. Złożoność obliczeniowa takiego sortowania pozycyjnego na pewno nie będzie O(n). Wynika to z tego, że do posortowania np. nazwisk trudno jest użyć sortowania przez zliczanie.

[14] Elementarne metody wyszukiwania. Haszowanie. 1.1. Wyszukiwanie liniowe/sekwencyjne Wyszukiwanie liniowe (ang. linear search), zwane również sekwencyjnym (ang. sequential search) polega na przeglądaniu kolejnych elementów zbioru Z. Jeśli przeglądany element posiada odpowiednie własności (np. jest liczbą o poszukiwanej wartości), to zwracamy jego pozycję w zbiorze i kooczymy. W przeciwnym razie kontynuujemy poszukiwania aż do przejrzenia wszystkich pozostałych elementów zbioru Z. W przypadku pesymistycznym, gdy poszukiwanego elementu nie ma w zbiorze lub też znajduje się on na samym koocu zbioru, algorytm musi wykonać przynajmniej n obiegów pętli sprawdzającej poszczególne elementy. Wynika z tego, iż pesymistyczna klasa złożoności obliczeniowej jest równa O(n), czyli jest liniowa - stąd pochodzi nazwa metody wyszukującej. Często chcemy znaleźć wszystkie wystąpienia w zbiorze poszukiwanej wartości elementu. W takim przypadku algorytm na wejściu powinien otrzymywać dodatkowo pozycję (indeks) elementu, od którego ma rozpocząd wyszukiwanie. Pozycję tę przy kolejnym przeszukiwaniu podajemy zawsze o 1 większą od ostatnio znalezionej. Dzięki temu nowe poszukiwanie rozpocznie się tuż za poprzednio znalezionym elementem. Schemat algorytmu: n - liczba elementów w tablicy Z* +, n N Z[ ]- tablica zawierająca elementy do przeszukania. Indeksy elementów rozpoczynają się od 0, a kooczą na n-1 p - indeks pierwszego elementu Z* +, od którego rozpoczniemy poszukiwania. p C k - poszukiwana wartość, czyli tzw. klucz, wg którego wyszukujemy elementy w Z* + 01: Dla i = p,p+1,...,n-1: wykonuj krok 2 ; przeglądamy kolejne elementy w zbiorze 02: Jeśli Z[i] = k, to zakoocz zwracając i ; jeśli napotkamy poszukiwany element, zwracamy jego pozycję 03: Zakończ zwracając -1 ; jeśli elementu nie ma w tablicy, zwracamy -1 1.2. Wyszukiwanie binarne Wyszukiwanie binarne jest algorytmem opierającym się na metodzie dziel i zwyciężaj, który w czasie logarytmicznym stwierdza, czy szukany element znajduje się w uporządkowanej tablicy i jeśli się znajduje, podaje jego indeks. Np. jeśli tablica zawiera milion elementów, wyszukiwanie binarne musi sprawdzić maksymalnie 20 elementów () w celu znalezienia żądanej wartości. Dla porównania wyszukiwanie liniowe wymaga w najgorszym przypadku przeglądnięcia wszystkich elementów tablicy. Zasada działania : Jeśli zbiór jest pusty, to kooczymy algorytm z wynikiem negatywnym. W przeciwnym razie wyznaczamy element leżący w środku zbioru. Porównujemy poszukiwany element z elementem środkowym. Jeśli są sobie równe, to zadanie wyszukania elementu jest wypełnione i kooczymy algorytm. W przeciwnym razie element środkowy dzieli zbiór na dwie partycje - lewą z elementami mniejszymi od środkowego oraz prawą z elementami większymi. Jeśli porównywany element jest mniejszy od środkowego elementu zbioru, to za nowy zbiór poszukiwao przyjmujemy lewą partycję. W przeciwnym razie za nowy zbiór przyjmujemy prawą partycję. W obu przypadkach rozpoczynamy poszukiwania od początku, ale w nowo wyznaczonym zbiorze.

1.3. Wyszukiwanie max lub min Zadanie znajdowania elementu maksymalnego lub minimalnego jest typowym zadaniem wyszukiwania, które rozwiązujemy przy pomocy algorytmu wyszukiwania liniowego. Za tymczasowy maksymalny (minimalny) element przyjmujemy pierwszy element zbioru. Następnie element tymczasowy porównujemy z kolejnymi elementami. Jeśli któryś z porównywanych elementów jest większy (mniejszy) od elementu tymczasowego, to za nowy tymczasowy element maksymalny (minimalny) przyjmujemy porównywany element zbioru. Gdy cały zbiór zostanie przeglądnięty, w elemencie tymczasowym otrzymamy element maksymalny (minimalny) w zbiorze. Poniżej podajemy algorytm wyszukiwania max. Wyszukiwanie min wykonuje się identycznie, zmianie ulega tylko warunek porównujący element tymczasowy z elementem zbioru Schemat algorytmu: n - liczba elementów w tablicy Z* +, n N Z[ ] - tablica zawierająca elementy do zliczania. Indeksy elementów rozpoczynają się od 0, a kooczą na n - 1.. maxz - tymczasowy element maksymalny 1: maxz Z[0] ; za tymczasowy element maksymalny bierzemy pierwszy element 2: Dla i = 1,2,...,n-1 wykonuj K03 ; przeglądamy następne elementy zbioru 3: Jeśli Z[i] > maxz, to maxz Z[i] ; jeśli natrafimy na większy od maxz, to zapamiętujemy go w maxz 4: Zakoocz zwracając maxz 2.4. Naiwne wyszukiwanie wzorca w tekście Algorytm N - naiwny - ustawia okno o długości wzorca p na pierwszej pozycji w łańcuchu s. Następnie sprawdza, czy zawartość tego okna jest równa wzorcowi p. Jeśli tak, pozycja okna jest zwracana jako wynik, po czym okno przesuwa się o jedną pozycję w prawo i cała procedura powtarza się. Algorytm kończymy, gdy okno wyjdzie poza koniec łańcucha. Klasa pesymistycznej złożoności obliczeniowej algorytmu N jest równa O(n m), gdzie n oznacza liczbę znaków tekstu, a m liczbę znaków wzorca. Jednakże w typowych warunkach algorytm pracuje w czasie O(n), ponieważ zwykle wystarczy porównanie kilku początkowych znaków okna z wzorcem, aby stwierdzić, iż są one niezgodne. 2.5. Alogorytm Karpa-Rabina Danemu wzorcu możemy przyporządkować odpowiadającą mu wartość dziesiętną - klucz. Dla danego tekstu obliczamy wartości dziesiętne kolejnych podsłów długości wzorca zaczynając od początku tekstu uzyskujemy różne klucze. Teraz wystarczy porównać wartość dziesiętną odpowiadającą wzorcu z wartościami dziesiętnymi odpowiadającymi kolejnym podsłowom czyli sprawdzamy czy klucze są identyczne. Jeżeli są one równe możemy podejrzewać, że wzorzec występuje w tekście. 2.6 Haszowanie Haszowanie jest to pewna technika rozwiązywania ogólnego problemu słownika. Przez problem słownika rozumiemy tutaj takie zorganizowanie struktur

danych i algorytmów, aby można było w miarę efektywnie przechowywać i wyszukiwać elementy należące do pewnego dużego zbioru danych (uniwersum). Przykładem takiego uniwersum mogą być liczby lub napisy (wyrazy) zbudowane z liter jakiegoś alfabetu.