9. Palindromy
Transkrypt
9. Palindromy
Palindromy Palindromem (z greckiego) nazywamy wyraz, który tak samo brzmi, gdy jest czytany wspak. Palindromami są na przykład takie wyrazy, jak kajak, zaraz, oko, zakaz, mam itp. Użytkownik wprowadza ciąg znaków s. Podaj algorytm sprawdzania, czy s jest palindromem. (Np.: po wprowadzeniu ciągu znaków kajak w programie powinien pojawić się komunikat „tak”, natomiast po wprowadzeniu ciągu znaków canoe powinien pojawić się komunikat „nie”). Specyfikacja algorytmu: Dane wejściowe: ciąg znaków s Dane wyjściowe: komunikat „tak” lub „nie” w zależności od tego, czy s jest palindromem a) Przedstaw ten algorytm w formie opisu kolejnych kroków. b) Zaprezentuj ten algorytm w formie schematu blokowego. c) Napisz program realizujący ten algorytm w wybranym przez siebie języku programowania (Pascal, C lub C++). Oto przykład działania takiego programu: Podaj ciąg znaków: Tak kajak Podaj ciąg znaków: Nie canoe d) Zaimplementuj ten algorytm w formie programu w języku Visual Basic lub skryptu w języku JavaScript. Oto przykładowy projekt takiej aplikacji (poniżej po lewej) oraz komunikat, jaki powinien pojawić się po kliknięciu na przycisku (poniżej po prawej): Przykładowe rozwiązanie Poniższe rozwiązanie opiera się użyciu dwóch pomocniczych zmiennych (oznaczmy je przez i oraz j), które oznaczają pozycje znaków w ciągu. Na początku ustawiamy i na początku wyrazu, zaś j na jego końcu. Porównujemy znaki znajdujące się na tych miejscach i jeśli się zgadzają, wtedy i powiększamy o 1, zaś j zmniejszamy o 1, sprawdzamy znaki itd. Procedurę sprawdzania kontynuujemy, jeśli i jest mniejsze od j – nastąpi taki moment, gdy i zrówna się z j lub go przekroczy (zależy to od parzystości liczby znaków w ciągu). Jeśli w jakimkolwiek momencie napotkamy na rozbieżność, czyli różne znaki na miejscach i oraz j, wtedy przerywamy sprawdzanie – sprawdzany ciąg nie jest palindromem. Jeśli natomiast sprawdzanie dobiegło spokojnie do końca, wówczas ciąg jest palindromem. Ponadto będzie nam potrzebna funkcja zwracająca długość ciągu znaków – przyjmiemy, iż nazywa się ona po prostu długość. Przez s[i] oznaczać będziemy i-ty znak ciągu i założymy, że znaki ciągu s numerowane są od 1 do długość(s). Specyfikację algorytmu uzupełniamy o poniższy zapis: liczby naturalne i, j Zmienne pomocnicze: Funkcja pomocnicza: Notacja: długość – jej argumentem jest ciąg znaków, zwraca długość (ilość znaków) tego ciągu s[i] – i-ty znak ciągu s znaki w ciągu numerowane są od 1 Opis kolejnych kroków – pkt a) Krok 1: Wczytaj ciąg znaków s. Krok 2: Zmiennej i przypisz wartość 1, zaś zmiennej j przypisz wartość długość(s). Krok 3: Jeśli i jest większe lub równe j, wtedy wypisz komunikat „tak” i zakończ działanie algorytmu. Krok 4: Jeśli s[i] jest różne od s[j], wtedy wypisz komunikat „nie” i zakończ działanie algorytmu. Krok 5: Powiększ o 1 zmienną i oraz pomniejsz o 1 zmienną j. Krok 6: Przejdź do kroku 3. Schemat blokowy – pkt b) Start i←1 j ← długość(s) Wczytaj s NIE NIE i←i+1 j←j−1 s[i] ≠ s[j] ? TAK i≥j ? TAK Wypisz „tak” Wypisz „nie” Stop Program w języku Pascal – pkt c) program Palindrom; { Sprawdzanie, czy wprowadzony ciąg znaków jest palindromem } var s: string; i, j: integer; begin write('Podaj ciąg znaków: '); readln(s); i := 1; { numer pierwszego znaku } j := length(s); { numer ostatniego znaku } while i<j do begin if s[i]<>s[j] then begin { znaki różnią się} writeln('Nie'); halt end; { sprawdzamy dalej } i := i+1; j := j-1 end; { sprawdzenie dobiegło pomyślnie do końca } writeln('Tak') end. Program w języku C++ – pkt c) // Sprawdzanie, czy wprowadzony ciąg znaków jest palindromem #include <iostream> #include <string> // największa długość ciągu znaków #define MAX 100 main() { char s[MAX+1]; // dodajemy jedno miejsce // na znak zakończenia cout << "Podaj ciąg znaków: "; cin >> s; int i, j; i = 0; // numer pierwszego znaku j = strlen(s)-1; // numer ostatniego znaku while(i<j) { if(s[i]!=s[j]) { // znaki różnią się cout << "Nie\n"; exit(0); } // sprawdzamy dalej i++; j--; } // sprawdzenie dobiegło pomyślnie do końca cout << "Tak\n"; } Uwaga: Wartości początkowe zmiennych i oraz j są nieco modyfikowane ze względu na inny sposób numeracji elementów tablicy w języku C++. Program w języku Visual Basic – pkt d) Pole tekstowe, na którym użytkownik wpisuje ciąg znaków, jest oznaczone jako Text1. Przycisk uruchamiający procedurę sprawdzajacą jest oznaczony jako Command1. Komunikat jest wyświetlany przy użyciu procedury MsgBox. Oto procedura stowarzyszona z przyciskiem Command1: Private Sub Command1_Click() Dim s, i, j ' odczytanie wprowadzonych danych s = Text1.Text ' numer pierwszego znaku i = 1 ' numer ostatniego znaku j = Len(s) Do While i < j If Mid(s, i, 1) <> Mid(s, j, 1) Then ' znaki różnią się MsgBox ("Nie") Exit Sub End If ' sprawdzamy dalej i = i + 1 j = j - 1 Loop ' sprawdzenie dobiegło pomyślnie do końca MsgBox ("Tak") End Sub Uwaga: Użycie funkcji Mid umożliwia dostęp do poszczególnych fragmentów ciągu znaków – w tym przypadku do pojedynczych znaków. Program w języku JavaScript – pkt d) Prezentujemy kompletny kod HTML strony WWW będącej rozwiązaniem zadania: <html> <head> <script language=javascript> function sprawdz() { // odczytanie wprowadzonych danych var s = document.form1.wyraz.value; var i = 0; var j = s.length-1; // numer pierwszego znaku // numer ostatniego znaku while(i<j) { if(s.charAt(i)!=s.charAt(j)) { // znaki różnią się alert("Nie"); return; } // sprawdzamy dalej i++; j--; } // sprawdzenie dobiegło pomyślnie do końca alert("Tak"); } </script> </head> <body> <h1 align=center>Palindromy</h1> <center> <form name=form1> Podaj wyraz: <input type=text size=30 name=wyraz> <br><br> <input type=button value="Sprawdź czy jest palindromem" onClick=sprawdz()> </form> </center> </body> </html> Uwaga: Funkcja (czy raczej metoda) charAt umożliwia dostęp do pojedynczych znaków w ciągu.