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: kajak Tak Podaj ciąg znaków: canoe Nie 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: Zmienne pomocnicze: Funkcja pomocnicza: Notacja: liczby naturalne i, j 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: Krok 3: Krok 4: Zmiennej i przypisz wartość 1, zaś zmiennej j przypisz wartość długość(s). Jeśli i jest większe lub równe j, wtedy wypisz komunikat tak i zakończ działanie algorytmu. 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 Wczytaj s i 1 j długość(s) NIE i j? TAK NIE s[i] s[j]? TAK Wypisz tak i i + 1 j j 1 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; write('podaj ciąg znaków: '); readln(s); i := 1; numer pierwszego znaku j := length(s); numer ostatniego znaku while i<j do if s[i]<>s[j] then 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; // numer pierwszego znaku var j = s.length-1; // 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.