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.