Szyfr Cezara, wyszukiwanie wzorca, operacje na lancuchach znakow
ð Podstawa programowa: II.1+I.2bLancuchy znakow (stringi) to jeden z najczesciej uzywanych typow danych. Python oferuje bogaty zestaw narzedzi do pracy z tekstem. Pamietaj, ze stringi sa niemutowalne - kazda operacja tworzy nowy lancuch.
# Podstawowe operacje
tekst = "Informatyka w liceum"
print(len(tekst)) # 20 (dlugosc)
print(tekst[0]) # 'I' (pierwszy znak)
print(tekst[-1]) # 'm' (ostatni znak)
print(tekst[0:11]) # 'Informatyka' (wycinanie)
print(tekst.upper()) # 'INFORMATYKA W LICEUM'
print(tekst.lower()) # 'informatyka w liceum'
print(tekst.count('a')) # 2 (liczba wystapien)
print(tekst.find('w')) # 12 (indeks pierwszego wystapienia)
print(tekst.replace('liceum', 'szkole')) # zamiana
# Kody ASCII
print(ord('A')) # 65
print(ord('a')) # 97
print(chr(65)) # 'A'
print(chr(97)) # 'a'
Szyfr Cezara to jeden z najstarszych i najprostszych szyfrow. Polega na przesunieciu kazdej litery w tekscie o stala liczbe pozycji w alfabecie. Na przyklad przy przesunieciu o 3: A staje sie D, B staje sie E itd. Juliusz Cezar uzywal tego szyfru do tajnej korespondencji wojskowej.
def szyfr_cezara(tekst, klucz):
"""Szyfrowanie szyfrem Cezara"""
wynik = ""
for znak in tekst:
if znak.isalpha():
# Ustalamy baze (duze/male litery)
baza = ord('A') if znak.isupper() else ord('a')
# Przesuniecie z zawijaniem (modulo 26)
nowy_kod = (ord(znak) - baza + klucz) % 26 + baza
wynik += chr(nowy_kod)
else:
wynik += znak # znaki niebedace literami bez zmian
return wynik
def deszyfruj_cezara(tekst, klucz):
"""Deszyfrowanie = szyfrowanie z ujemnym kluczem"""
return szyfr_cezara(tekst, -klucz)
# Przyklad
oryginal = "Witaj w swiecie informatyki!"
zaszyfrowany = szyfr_cezara(oryginal, 3)
odszyfrowany = deszyfruj_cezara(zaszyfrowany, 3)
print(f"Oryginal: {oryginal}")
print(f"Zaszyfrowany: {zaszyfrowany}")
print(f"Odszyfrowany: {odszyfrowany}")
Wyszukiwanie wzorca (pattern matching) polega na znalezieniu wszystkich wystapien danego podciagu (wzorca) w dluzszym tekscie. Algorytm naiwny porownuje wzorzec z kazdym mozliwym polozeniem w tekscie.
def wyszukaj_wzorzec(tekst, wzorzec):
"""Naiwne wyszukiwanie wzorca - zwraca liste pozycji"""
pozycje = []
n = len(tekst)
m = len(wzorzec)
for i in range(n - m + 1):
znaleziono = True
for j in range(m):
if tekst[i + j] != wzorzec[j]:
znaleziono = False
break
if znaleziono:
pozycje.append(i)
return pozycje
# Przyklad
tekst = "abrakadabra"
wzorzec = "abra"
wynik = wyszukaj_wzorzec(tekst, wzorzec)
print(f"Wzorzec '{wzorzec}' znaleziony na pozycjach: {wynik}")
# [0, 7]
Czesta operacja na tekstach to analiza czestosc wystepowania znakow, co moze byc uzyte np. do lamania szyfrow:
def analiza_czestosci(tekst):
"""Liczy czestotliwosc kazdej litery w tekscie"""
czestosci = {}
for znak in tekst.lower():
if znak.isalpha():
czestosci[znak] = czestosci.get(znak, 0) + 1
# Sortowanie po czestosci malejaco
posortowane = sorted(czestosci.items(), key=lambda x: x[1], reverse=True)
return posortowane
tekst = "To jest przykladowy tekst do analizy czestosci liter"
for litera, ile in analiza_czestosci(tekst):
print(f"'{litera}': {ile}")
Napisz program, ktory pobiera od uzytkownika tekst i klucz (przesuniecie), a nastepnie szyfruje i deszyfruje tekst szyfrem Cezara. Program powinien obslugiwac zarowno male, jak i duze litery.
def szyfr_cezara(tekst, klucz):
wynik = ""
for znak in tekst:
if znak.isalpha():
baza = ord('A') if znak.isupper() else ord('a')
nowy_kod = (ord(znak) - baza + klucz) % 26 + baza
wynik += chr(nowy_kod)
else:
wynik += znak
return wynik
tekst = input("Podaj tekst: ")
klucz = int(input("Podaj klucz (przesuniecie): "))
zaszyfrowany = szyfr_cezara(tekst, klucz)
odszyfrowany = szyfr_cezara(zaszyfrowany, -klucz)
print(f"Zaszyfrowany: {zaszyfrowany}")
print(f"Odszyfrowany: {odszyfrowany}")
Napisz program, ktory probouje zlamac szyfr Cezara metoda brute-force - wyswietla wszystkie 25 mozliwych odszyfrowanych tekstow. Przetestuj na: "Zlwdm z vzlhflh lqirupdwbnl!"
def szyfr_cezara(tekst, klucz):
wynik = ""
for znak in tekst:
if znak.isalpha():
baza = ord('A') if znak.isupper() else ord('a')
nowy_kod = (ord(znak) - baza + klucz) % 26 + baza
wynik += chr(nowy_kod)
else:
wynik += znak
return wynik
zaszyfrowany = "Zlwdm z vzlhflh lqirupdwbnl!"
print("Probowanie wszystkich kluczy:")
for klucz in range(1, 26):
odszyfrowany = szyfr_cezara(zaszyfrowany, -klucz)
print(f"Klucz {klucz:2d}: {odszyfrowany}")
Napisz program, ktory wyszukuje wzorzec w tekscie i wyswietla tekst z podswietlonymi (oznaczonymi gwiazdkami) miejscami wystapienia wzorca. Np. dla tekstu "abrakadabra" i wzorca "abra" wynik to: "*abra*kad*abra*".
def wyszukaj_i_podswietl(tekst, wzorzec):
pozycje = []
n = len(tekst)
m = len(wzorzec)
for i in range(n - m + 1):
if tekst[i:i+m] == wzorzec:
pozycje.append(i)
if not pozycje:
return tekst, pozycje
wynik = ""
i = 0
while i < n:
if i in pozycje:
wynik += f"*{tekst[i:i+m]}*"
i += m
else:
wynik += tekst[i]
i += 1
return wynik, pozycje
tekst = "abrakadabra"
wzorzec = "abra"
podswietlony, poz = wyszukaj_i_podswietl(tekst, wzorzec)
print(f"Tekst: {tekst}")
print(f"Wzorzec: {wzorzec}")
print(f"Pozycje: {poz}")
print(f"Wynik: {podswietlony}")
Napisz funkcje: czy_palindrom(tekst) sprawdzajaca czy tekst jest palindromem (pomijajac spacje i wielkosc liter) oraz czy_anagram(s1, s2) sprawdzajaca czy dwa slowa sa anagramami. Przetestuj na przykladach.
def czy_palindrom(tekst):
oczyszczony = ''.join(c.lower() for c in tekst if c.isalpha())
return oczyszczony == oczyszczony[::-1]
def czy_anagram(s1, s2):
s1_clean = sorted(s1.lower().replace(' ', ''))
s2_clean = sorted(s2.lower().replace(' ', ''))
return s1_clean == s2_clean
# Testy palindromu
palindromy = ["kajak", "Ala ma kota a tok am Ala", "Anna", "Python"]
for p in palindromy:
print(f"'{p}' palindrom? {czy_palindrom(p)}")
print()
# Testy anagramow
pary = [("listen", "silent"), ("hello", "world"), ("anagram", "nagaram")]
for s1, s2 in pary:
print(f"'{s1}' i '{s2}' anagramy? {czy_anagram(s1, s2)}")