3. hét: sztringműveletek
Czirkos Zoltán, Frey Balázs, Bulla Ádám · 2024.09.22.
Sztringekkel végzett műveletek. Sztringek beolvasása, darabolása, feldolgozása karakterenként.
Felkészülés a laborra:
- A nevezetes algoritmusok megértése.
- A sztringekről tanultak átolvasása.
Írj programot, amelyik egy mondatról eldönti, hogy palindrom-e. Közismert magyar nyelvű palindrom mondat az „Indul a görög aludni.” Ez abban különbözik az előző feladattól, hogy most a szóközöket és az írásjeleket ki kell szűrnöd, vagyis csak a betűket kell megtartani, és úgy kell vizsgálni a sztringet. És persze figyelni arra is, hogy a kisbetűk és a nagybetűk nem különböznek.
Megoldás
Első lehetőség: hibát keresünk a sztringben (van-e benne hiba: eldöntés tétele). Vagyis olyan betűpárt, aminek egyeznie kellene, de nem egyezik. Ehhez elmegyünk a sztring közepéig, és minden karaktert összehasonlítunk azzal, amelyik a végétől visszafelé számítva ugyanolyan kellene legyen.
szo = "görög"
hibas = False
index = 0
hossz = len(szo)
while index < hossz / 2 and not hibas:
if szo[index] != szo[hossz - 1 - index]:
hibas = True
index += 1
if hibas:
print("Nem palindrom")
else:
print("Palindrom")
Másik lehetőség, hogy megépítjük a fordított sztringet, és összehasonlítjuk az eredetivel:
szo = "abcd"
forditva = ""
for c in szo:
forditva = c + forditva # a, ba, cba, dcba
if szo == forditva:
print("Palindrom")
else:
print("Nem palindrom")
Tipp
Érdemes előállítani a sztringnek egy olyan kisbetűsített változatát, amiben semmi nem marad meg a betűkön kívül – vagyis eltűnnek a szóközök és az írásjelek is. Betű-e – nézz szét a sztring típus függvényei között!
Megoldás
szoveg = "Indul a görög aludni."
csakbetuk = ""
for i in szoveg:
if i.isalnum():
csakbetuk += i.lower()
hibas = False
index = 0
hossz = len(csakbetuk)
while index < hossz / 2:
if csakbetuk[index] != csakbetuk[hossz - 1 - index]:
hibas = True
break
index += 1
if hibas:
print("A megadott szó nem palindrom!")
else:
print("A megadott szó palindrom!")
A fordított szöveg vizsgálata így is elvégezhető (előadáson nem szerepelt):
if csakbetuk != csakbetuk[::-1]:
print("A megadott szöveg nem palindrom!")
else:
print("A megadott szöveg palindrom!")
Írj programot, amely madárnyelven (mavadávárnyevelveven) írja ki a beírt szöveget! Ezt azt jelenti, hogy minden magánhangzó után tesz egy v-t is, és megismétli a magánhangzót. Pl. te → teve, ma → mava, labor → lavabovor.
Valósítsd meg ezt úgy, hogy a beolvasott sor alapján egy új sztringet állítasz elő, és végül azt írod ki! Használd a tanult sztringműveleteket!
Megoldás
beirt = input()
madar = ""
for c in beirt:
madar += c
cl = c.lower()
if cl == 'a' or cl == 'e' or cl == 'i' or cl == 'o' or cl == 'u':
madar += 'v' + c.lower()
print(madar)
Persze a magánhangzók vizsgálata megoldható másképp is, például:
if "aeiou".find(c.lower()) != -1:
Kicsit előreszaladva az in
operátorhoz, amely az előadáson majd
szerepel, akár így is:
if c.lower() in "aeiou":
Gyakori feladat, hogy egy sztring elejéről és végéről el kell távolítani a szóközöket. Ezt a függvényt gyakran trim-nek vagy strip-nek szokták hívni.
Pythonban is van ilyen: " helló világ ".strip()
értéke "helló világ"
.
A feladatod megírni ezt az algoritmust, hogy megértsd a működését! Írj olyan programot, ami kér egy szöveget, és eltávolítja annak elejéről és végéről a szóközöket. Írd ki utána idézőjelek között a vágott sztringet!
Ha elkészültél, ellenőrizd, működik-e a programod olyan sztringre, ami csak szóközt tartalmaz, vagy esetleg eleve teljesen üres! Ha nem, javítsd ki!
Megoldás
A sztring végének kezelésénél jobban kell ügyelni. str[len(str)]
már nem indexelhető, és a vágásnál is jobbról
(végén) nyílt intervallumot kell megadni. A mintamegoldásban az eleje
és vege
változók azokra az
indexekre állnak be a sztring elején és végén, ahol nem szóköz van; a vágásnál ezért vege+1
-et kell írni.
szoveg = input("Írj be egy szöveget: ")
eleje = 0
while eleje < len(szoveg) and szoveg[eleje] == ' ':
eleje += 1
vege = len(szoveg)-1
while vege >= 0 and szoveg[vege] == ' ':
vege -= 1
vagott = szoveg[eleje:vege+1]
print('"{}"'.format(vagott))
Mi történik, ha az első ciklus feltételeit megfordítod? Miért?
Sok programozási nyelv a logikai műveleteknél nem ragaszkodik mindkét feltétel kiértékeléséhez, amennyiben az első után egyértelműen eldönthető, hogy az igaz vagy hamis lesz. Ha egy ÉS kapcsolatban az első feltétel hamis, a második értéke nem befolyásolja a végső eredményt, biztos, hogy hamis lesz. Ugyanez VAGY kapcsolatnál, amennyiben az első feltétel igaz. Ekkor a második feltétel kiértékelése nélkül meg tudjuk állapítani, hogy végül igaz eredményt kapunk. Erről még lesz szó előadáson.
A feladat: megcserélni egy névben a keresztnevet és a vezetéknevet, és az eredményt egy másik sztringben előállítani.
eredeti = "Gipsz Jakab"
... itt bármit csinálhatunk...
print("|" + forditott + "|") # |Jakab Gipsz|
Megoldás
Első megoldás: vágással. Megkeressük a szóközt, és utána ott „megfelezzük” a sztringet.
szokoz = 0
while eredeti[szokoz] != ' ':
szokoz += 1
forditott = eredeti[szokoz+1:] + ' ' + eredeti[:szokoz]
A szóköz megkereséséhez akár az eredeti.find(' ')
kifejezést is használhatnánk.
Második megoldás: a sztringek .split()
függvényével. Ez a megadott karakter mentén
darabokra vágja a sztringet, és a darabokat egy listába teszi.
darabolt = eredeti.split(' ')
forditott = darabolt[1] + ' ' + darabolt[0]
Írj programot, amelyik a beírt sorból olyan sztringet állít elő, amelyben VÉletLEnszErŰeN VÁLtAkoZnAK a kis- és nagybetűk! Használd az előadáson tanult sztringműveleteket!
Pythonban véletlenszámot a random
modul (import random
) egyik függvényével tudsz létrehozni.
Ennek neve: random.randint()
. Paramétere egy alsó és egy felső határ; random.randint(0, 1)
véletlenszerűen
0-t vagy 1-et ad.
Tipp
Figyelj a feladatkiírás pontos értelmezésére: nem csak SpoNGyaBobOSAn kiírni kell a sztringet, hanem egy új sztringet kell előállítanod egy változóban, amely ilyen formában tartalmazza a szöveget!
Logikus lenne arra gondolni, hogy a beolvasott sztring karaktereit módosítod, de ilyet nem tudsz csinálni Pythonban: a sztring egyes karakterei nem írhatók felül. Egy üres sztringet kell létrehoznod, és ahhoz hozzáfűzni a karaktereket kisbetűsítve vagy nagybetűsítve.
Megoldás
import random
line = input()
mocking = ""
for ch in line:
if random.randint(0, 1) == 0:
mocking += ch.upper()
else:
mocking += ch.lower()
print(mocking)
Hasonló feladatok
Ha a fenti feladatok nehezen mentek, megoldhatsz pár hasonló feladatot a példatárból, mielőtt a következő feladatra rátérsz.
Vigyázz, a laborfeladatokat erősen ajánlott az utolsó feladatig megoldani, hogy a jövő hétre felkészült legyél. Ha nem sikerül, fejezd be őket otthon!
Készíts programot, amelyik szavakat kér a felhasználótól, és hozzáfűzi őket egy listához! A beolvasás álljon meg akkor, ha üres sort kap.
Írj be szavakat, majd jelezd üres sorral a lista végét! alma körte barack
Ha megvan mind, írd ki a beírt szavakat vesszővel elválasztva! Ügyelj arra, hogy ne legyen sehol felesleges szóköz vagy vessző,
és legyen pont a mondat végén! Ehhez nem lesz elég a print(lista)
, mert az egész más formátumban írja ki az
adatokat.
A beírt szavak: alma, körte, barack.
Tipp
Végjeles vagy előre adott hosszúságú sorozatról van szó? Mit jelent ez, hogy „a beolvasás üres sornál áll meg”? Hogy jelenik meg ez a ciklusfeltételben?
Megoldás
A beolvasásnál: érdemes egy szót előre beolvasni külön. Akkor már értelmezhetővé válik a ciklusfeltétel.
A kiírásnál: az első szót külön kell kezelni, mert az elé nem kell vesszőt írni. Vagy esetleg elágazást kell tenni a ciklusba, amely vesszőt ír ki (ha nem az utolsó szóról van szó) vagy pontot ír ki (ha az utolsóról).
print("Írj be szavakat, majd jelezd üres sorral a lista végét!")
szavak = []
szo = input() # !
while szo != "":
szavak.append(szo)
szo = input()
if len(szavak) == 0:
print("Nem írtál be semmit")
else:
print("A beírt szavak: ", end="")
print(szavak[0], end="") # !
i = 1
while i < len(szavak):
print(", " + szavak[i], end="")
i += 1
print(".")
P i t a g o r a s z i t a g o r a s z P t a g o r a s z P i a g o r a s z P i t g o r a s z P i t a o r a s z P i t a g r a s z P i t a g o a s z P i t a g o r s z P i t a g o r a z P i t a g o r a s
Írj egy programot, amely létrehoz egy tízelemű, sztringekből álló listát! Ebben egyetlen karakterből álló sztringek legyenek,
bennük Pitagorasz nevének betűivel: 'P'
, 'i'
és így tovább. Írja ki a program ezt a listát a képernyőre,
a betűket szóközökkel elválasztva!
Léptesd a lista összes elemét eggyel az eleje felé! A lista egyik végén kilépő elem jöjjön be a túlsó végén. Ismételd meg ezt a műveletet tízszer, közben mindig írd ki a listát! Az eredmény a jobb oldalon láthatóhoz hasonló kell legyen.
Vigyázz, nem az a feladat, hogy egy trükkös kiírást csinálj! A listát kell úgy megváltoztatni, hogy elmozduljanak benne az elemek. A kiírásnak mindig a lista elejétől a végéig kell haladnia, minden sorban. A kód felépítése tehát ez kell legyen:
CIKLUS 10-szer CIKLUS a kiírásához... itt csak printek vannak, nem változik a lista CIKLUS a léptetéshez... itt változik a lista, és nincsenek printek CIKLUS VÉGE
Tipp
Egyetlen listára van csak szükség, másikat nem kell létrehozni! Az első felülírható a másodikkal, a második a harmadikkal… Kérdés, az utolsó helyre ilyenkor mi kerül. Rajzold le, és gondold végig úgy, minek kell történnie!
Megoldás
A léptetésnél az elsőt félretesszük, aztán az egészet balra húzzuk, végül pedig a félretett elemet
betesszük a végére. A ciklus azért rövidebb, mert [i + 1]
indexelés is van benne!
lista = ['P', 'i', 't', 'a', 'g', 'o', 'r', 'a', 's', 'z']
# 10-szer
for _ in range(10):
# kiírás
for c in lista:
print(c, end=" ")
print()
# léptetés
temp = lista[0]
for i in range(0, len(lista) - 1):
lista[i] = lista[i + 1]
lista[len(lista) - 1] = temp
Másik lehetőség: pop()
-oljuk a nulladikat, aztán append()
-eljük a végére:
lista = ['P', 'i', 't', 'a', 'g', 'o', 'r', 'a', 's', 'z']
for _ in range(10):
for c in lista:
print(c, end=" ")
print()
temp = lista.pop(0)
lista.append(temp)
A karaktereket tartalmazó lista egyébként megépíthető így is:
karakterek = list("Pitagorasz")
Ez azért működik, mert bármi, amin for
ciklus használható, az listává is konvertálható egyesével.
A sztring pont ilyen. Később erről lesz szó.
A Caesar-féle kódolás lényege, hogy a titkosítandó szövegben minden betű helyett ábécében a következőt vesszük. Így lesz az „barack” szóból „cbsbdl”: b→c, a→b, r→s és így tovább.
Írj programot, amelyik beolvas egy szót, és kiírja a titkosított változatát! Csak az angol ábécé kisbetűs karaktereivel kell foglalkozni, minden más maradjon változatlanul. A „z” betűből legyen „a” betű!
Tipp
Az ord()
függvénnyel lehet lekérdezni a karakterkódot. Pl. a kis „a” betűnél ez 97, hozzáadva
egyet 98-at kapunk, ami meg pont a „b” betű kódja. Ezt megadja a chr()
függvény.
Ha a laborfeladatokkal elkészültél, dolgozz a példatárban lévő feladatokon, a szorgalmi feladatokon, a minta zárthelyin, vagy a házi feladatodon.
Informatikusok próbálják lekódolni az Algoritmusok és gráfok tárgyon tanult algoritmusokat. A félév elején még nem biztos, hogy minden egyszerűen menni fog, de ahogy megismeritek a vonatkozó adatszerkezeteket és nyelvi elemeket, egyre könnyebb lesz. Ezzel két legyet lehet ütni egy csapásra, mert két tantárgyat is gyakoroltok egyszerre.