Gyakorlati alapok
Palindróma
Érdekes elmejáték a palindróma: olyan szavakat, mondatokat keresünk, amelyek visszafelé olvasva is ugyanazt jelentik. Gondoljunk csak a kék szóra, de talán a legismertebb közülük a géza kék az ég mondat. (Angolban talán a legismertebb: Dot saw I was Tod.)
A játék alapjában véve teljesen csapongó, hiszen az esetek döntő többségében egyszerűen figyelmen kívül hagy néhány fontos nyelvtani szabályt.
Vegyük példának a géza kék az ég mondatot. Visszafelé olvasva vehetjük észre, hogy ha minden nyelvtani szabályt következetesen betartunk, akkor bizony már nem jön ki a palindróma:
Géza kék az ég
gé za kék azéG
Mik tehát ezek a nyelvtani szabályok?
-
nagybetűk használata,
-
szóközök következetes alkalmazása,
-
sok esetben ékezetek használata.
Nos, pontosan ez az, amit palindróma implementálásakor nem hagyhatunk figyelmen kívül, bár alapjában véve 2 lehetőségünk van: vagy megtartjuk vagy elvetjük a fenti nyelvtani szabályokat.
Az előbbi eset rém megnehezíti a probléma leprogramozását, sőt ha jobban belegondolunk, voltaképpen lehetetlenné is teszi, mivel például nagybetűk soha sem fordulnak elő szavak végén (lásd: azéG). Az ésszerűség keretein belül tehát nincs más lehetőségünk, mint elvetni azokat, azaz algoritmikusan megfogalmazva, a következőt kell tennünk:
-
be kell vinnünk a vizsgálandó szót, mondatot. Programozás-technikailag nézve a fogadó egy rugalmasan kezelhető String-típus, a StringBuffer lesz, amit később stabil String típusba konvertálhatunk.
-
Meg kell akadályozunk, hogy nagybetű kerüljön a rendszerbe. Erről a String osztály toLowerCase() metódusa gondoskodik, amely kisbetűsre alakít minden betűt.
-
Ha a vizsgálandó objektum mondat, belőle minden szóközt el kell távolítanunk egy for ciklus, valamint az isWhitespace() és a deleteCharAt() függvények segítségével.
-
A szót/mondatot meg kell fordítanunk a reverse() függvény segítségével.,
-
Meg kell vizsgálnunk, hogy az eredeti és a fordított szó, mondat egyenlő-e egymással (Mikor egyenlő az egyenlő avagy az equals() függvény című fejezet).
Az alábbi Java-kódban további érdekességek is fellelhetők. A String és StringBuffer típusok csak részben kompatibilisek egymással, ezért kis trükközésekhez kell folyamodnunk, hiszen például a StringBuffer osztálynak nincs toLowerCase() metódusa, a String osztálynak sem deleteCharAt(), sem reverse() függvénye. Ráadásul közvetlen összehasonlításukkor garantáltan hibás eredményeket fogunk kapni.
A kódban ugyanakkor észrevehető metódusláncolás is (method chaining), amely ugyan nehezebben olvasható, de mégis hatékonyabb kódot eredményez:
String szoReversedString = szo.reverse().toString().toLowerCase();
S emlékezzünk vissza: if(identical) azonos if(identical == true) állítással.
Nézzük meg a futtatható Java-kódot:
class Main {
public static void main (String args[]){
Character kar = new Character('0');
StringBuffer szo = new StringBuffer("Java");
for(int i = 0; i < szo.length(); i++){
boolean karWhitespace =
kar.isWhitespace(szo.charAt(i));
if(karWhitespace){
szo.deleteCharAt(i);
}
}
String szoOriginalString = szo.toString().toLowerCase();
System.out.println("Az eredeti szó/mondat szóköz nélkül: " +
szo);
System.out.println("Az eredeti szó/mondat kisbetűvel, szóköz
nélkül: " + szoOriginalString);
String szoReversedString = szo.reverse().toString().toLowerCase();
System.out.println("Az eredeti szó/mondat kisbetűvel, szóköz
nélkül, megfordítva: " + szoReversedString);
boolean identical = false;
identical = szoOriginalString.equals(szoReversedString);
System.out.print("Palindróma? ");
if(identical){
System.out.print("Igen.");
}
else
System.out.print("Nem.");
}
}
Végeredmény:
Az eredeti szó/mondat szóköz nélkül: Gézakékazég
Az eredeti szó/mondat kisbetűvel, szóköz nélkül: gézakékazég
Az eredeti szó/mondat kisbetűvel, szóköz nélkül, megfordítva: gézakékazég
Palindróma? Igen.
Az eredeti szó/mondat szóköz nélkül: Java
Az eredeti szó/mondat kisbetűvel, szóköz nélkül: java
Az eredeti szó/mondat kisbetűvel, szóköz nélkül, megfordítva: avaj
Palindróma? Nem.