Liceum Klasa III 45 minut PP: II.1+I.2b | s. 342-343

Lekcja 4: Programowanie algorytmow tekstowych - implementacja

Szyfr Cezara, wyszukiwanie wzorca, operacje na lancuchach znakow

📋 Podstawa programowa: II.1+I.2b
Pythonalgorytmyimplementacjaprogramowaniestringszyfr Cezarawyszukiwaniewyszukiwanie wzorca
00:00
Wprowadzenie
5 min
00:05
Teoria
15 min
00:20
Cwiczenia
15 min
00:35
Podsumowanie
10 min
📚

Teoria

Operacje na lancuchach znakow w Pythonie

Lancuchy 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

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.

Wzor matematyczny:
Szyfrowanie: C = (P + klucz) mod 26
Deszyfrowanie: P = (C - klucz) mod 26
gdzie P - pozycja litery w alfabecie, C - pozycja zaszyfrowanej litery
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 w tekscie

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]

Analiza tekstu

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}")
✏️

Zadania

Latwe

Zadanie 1: Szyfr Cezara - szyfrowanie i deszyfrowanie

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.

Pokaz rozwiazanie
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}")
Srednie

Zadanie 2: Lamanie szyfru Cezara

Napisz program, ktory probouje zlamac szyfr Cezara metoda brute-force - wyswietla wszystkie 25 mozliwych odszyfrowanych tekstow. Przetestuj na: "Zlwdm z vzlhflh lqirupdwbnl!"

Pokaz rozwiazanie
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}")
Srednie

Zadanie 3: Wyszukiwanie wzorca z podswietleniem

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*".

Pokaz rozwiazanie
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}")
Trudne

Zadanie 4: Palindrom i anagram

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.

Pokaz rozwiazanie
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)}")
🎥

Materialy wideo

Jak zakodować szyfr cezara w Python
DooMx
Algorithms on texts - searching for a pattern in text
Dziwne... u mnie działa - (ScratchSPWZ)
🎧

Podcasty

✔️

Quiz - sprawdz sie!

📜

Podstawa programowa

← Lekcja 3: Algorytmy sortowania Siatka godzinowa Lekcja 5: Elementy robotyki →