RmtGf1Gvh45gA
Fotografia przedstawia okulary i lupę powiększającą leżące na otwartej książce.

I_P_W14_M15_C++ Wyszukiwanie wzorca w tekście

Źródło: Wallace Chuck, domena publiczna.

Jak odnaleźć wzorzec w tekście?

Rozważmy następujący problem. Mamy ciąg znaków: jedno słowo (np. „kot”) lub kilka wyrazów – np. zdanie „ala ma kota” (dla uproszczenia pomijamy wielkości liter). Problem wyszukania wzorca w tekście polega na odnalezieniu takiej liczby, która określa, ile początkowych znaków tekstu należy usunąć, aby rozpoczynał się on właśnie od wzorca. W przytoczonym przykładzie taką cyfrą będzie 7. Po usunięciu z ciągu „ala ma kota” 7 początkowych znaków, zostaniemy z wyrażeniem „kota”. Wówczas łatwo zauważyć, że wzorzec „kot” pasuje do początku zdania.

W jaki sposób odbywa się szukanie wzorca w tekście? Pomocna jest tzw. metoda naiwna, określana często mianem brute forcebrute forcebrute force.

Polega ona na wykonywaniu porównania wzorca z początkiem tekstu dla każdej liczby znaków, które z niego usuniemy. Takie wyszukiwanie w podanym przykładzie będzie wyglądało następująco:

R1PPQUTSZhpVo
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Podstawową wadą tej metody jest to, że nie jest ona optymalna. Nie nadaje się do poszukiwania długich wzorców w długich tekstach. Istnieją algorytmy, które dużo efektywniej radzą sobie w podobnych sytuacjach. Jednym z takich algorytmów jest algorytm Knutha‑Morrisa‑Pratta.

Co to jest metoda naiwna?

Metoda naiwna polega na sprawdzaniu każdego możliwego miejsca w tekście, w którym wzorzec mógłby się zaczynać, i porównywaniu znak po znaku, czy wzorzec pasuje do fragmentu tekstu.

Nie jest to algorytm szczególnie wydajny, ale jego prostota sprawia, że jest idealnym punktem wyjścia do nauki bardziej zaawansowanych technik.

Idea działania

Załóżmy, że mamy tekst T o długości n i wzorzec P o długości m. Algorytm:

  1. Przesuwa wzorzec od początku tekstu aż do pozycji n - m.

  2. Na każdej pozycji sprawdza, czy znaki wzorca pasują do odpowiadających znaków tekstu.

  3. Jeśli wszystkie znaki pasują – mamy dopasowanie.

  4. Jeśli choć jeden znak się różni – przesuwamy wzorzec o jedną pozycję dalej.

Algorytm wyszukiwania pierwszego wystąpienia wzorca (metoda naiwna)

Dane wejściowe:
T - tekst, w którym szukamy wzorca,
W - tekst, będący wzorcem, którego szukamy
Wynik: indeks elementu, od którego rozpoczyna się pierwsze wystąpienie wzorca w tekście lub komunikat „BRAK” jeśli wzorzec nie występuje.

Lista kroków:

Linia 1. Ustal długości dwukropek. Linia 2. n – długość tekstu T przecinek. Linia 3. m – długość wzorca W kropka. Linia 4. Ustaw pozycję początkową i znak równości 0 kropka. Linia 5. Dopóki i ≤ n minus m dwukropek. Linia 6. Porównuj kolejno znaki wzorca W z odpowiadającymi im znakami tekstu T od pozycji i kropka. Linia 7. Jeśli wszystkie znaki się zgadzają → zwróć indeks i otwórz nawias okrągły to pierwsze wystąpienie wzorca zamknij nawias okrągły kropka. Linia 8. Zakończ program. Linia 9. W przeciwnym razie przesuń się o jedno miejsce w prawo otwórz nawias okrągły i znak równości i plus 1 zamknij nawias okrągły kropka. Linia 10. Jeśli po sprawdzeniu wszystkich możliwych pozycji nie znaleziono dopasowania przecinek zwróć komunikat dwukropek cudzysłów brak wzorca w tekście cudzysłów kropka.

Przykład działania:

Tekst: T = „ababcababc”
Wzorzec: W = „abc”
n = 10
m = 3
Porównuje „abc” z T[0..2] → nie pasuje
Porównuje „abc” z T[1..3] → nie pasuje
Porównuje „abc” z T[2..4] → pasuje 

Wynik: pierwsze wystąpienie na pozycji 2

brute force
brute force

 (z ang. brutalna siła) metoda polegająca na sprawdzeniu wszystkich możliwych przypadków w celu znalezienia rozwiązania danego problemu; terminu tego często używa się w kontekście prób łamania haseł, które polegają na sprawdzaniu wszystkich możliwych kombinacji znaków