średniStruktury danychPythonC++

Słowniki (Python) i Mapy (C++) na Maturze z Informatyki

15 min czytania
Python, C++
Zaktualizowano: 3.11.2025

Słownik (w Pythonie dict) lub mapa (w C++ std::map) to jedna z najważniejszych struktur danych, jakie poznasz. Zapomnij o indeksach 0, 1, 2... Tutaj sam decydujesz, jaki jest 'indeks'. Działa to jak prawdziwy słownik: masz unikalne klucze (np. słowo 'jabłko') i przypisane do nich wartości (np. definicję 'czerwony owoc'). Zamiast pytać 'co jest na pozycji 5?', pytasz 'jaka jest wartość dla klucza 'jabłko'?'. To fundamentalna zmiana: dostęp do danych masz nie przez numeryczną pozycję, ale przez unikalny identyfikator, który sam nadajesz. To, co czyni słowniki tak potężnymi, to ich szybkość. Znalezienie wartości dla danego klucza jest niemal natychmiastowe (złożoność O(1) w Pythonie), niezależnie od tego, czy słownik ma 10, czy 10 milionów elementów.

Dlaczego to ważne? Na maturze słowniki to Twoje sekretne narzędzie do zliczania i grupowania. Ile razy wystąpiła każda liczba w pliku? Słownik. Jaka jest łączna suma punktów dla każdego ucznia? Słownik (klucz: imię ucznia, wartość: suma). Ile razy wystąpiła każda litera? Słownik. Zamiast pisać skomplikowane pętle i sortowania, słownik rozwiązuje te problemy w kilku linijkach.

Teoria

Słownik (mapa) to struktura przechowująca dane w postaci par klucz-wartość. Każdy klucz w słowniku musi być unikalny. Klucze w Pythonie muszą być niemutowalne (np. liczby, stringi, krotki), w C++ muszą być porównywalne. Struktura ta pozwala na błyskawiczne dodawanie, usuwanie i wyszukiwanie elementów na podstawie ich klucza.

Jak to działa?

  1. Tworzenie: W Pythonie moj_slownik = {}. W C++ map moja_mapa;.
  2. Dodawanie / Modyfikacja: slownik[klucz] = wartosc. Jeśli klucz nie istnieje, nowa para jest tworzona. Jeśli klucz już istnieje, jego wartosc jest nadpisywana.
  3. Odczyt Wartości: wartosc = slownik[klucz]. W Pythonie, próba odczytu nieistniejącego klucza rzuci błąd KeyError.
  4. Bezpieczny Odczyt (Python): Użyj slownik.get(klucz, domyslna_wartosc). Jeśli klucza nie ma, zwróci domyslna_wartosc (np. 0 lub None) zamiast błędu.
  5. Sprawdzanie Klucza (Python): Najlepszy sposób to if klucz in slownik:. To sprawdza, czy klucz jest w słowniku.
  6. Iteracja (Python): Możesz iterować po kluczach (for klucz in slownik: lub slownik.keys()), po wartościach (slownik.values()) lub po obu na raz (for klucz, wartosc in slownik.items():).

Złożoność: Złożoność czasowa: Python (dict) - bazuje na tablicy haszującej. Średnia złożoność dodawania, usuwania i wyszukiwania to O(1) (czas stały). To jest niesamowicie szybkie. C++ (std::map) - bazuje na zrównoważonych drzewach (red-black tree). Złożoność dodawania, usuwania i wyszukiwania to O(log n). Wciąż bardzo szybko. (C++ ma też std::unordered_map, które działa jak dict w Pythonie, ze złożonością O(1)).

Implementacja

Podstawy: Tworzenie, Dostęp, Modyfikacja

Python
# 1. Tworzenie i dodawanie
uczniowie = {}
uczniowie["Jan"] = 100
uczniowie["Anna"] = 95
uczniowie["Piotr"] = 80
# {'Jan': 100, 'Anna': 95, 'Piotr': 80}

# 2. Modyfikacja (nadpisanie wartości)
uczniowie["Anna"] = 98
# {'Jan': 100, 'Anna': 98, 'Piotr': 80}

# 3. Odczyt (niebezpieczny)
# print(uczniowie["Kasia"]) # Rzuci błąd KeyError

# 4. Bezpieczne sprawdzanie (NAJWAŻNIEJSZE)
klucz = "Kasia"
if klucz in uczniowie:
    print(f"{klucz} ma {uczniowie[klucz]} pkt")
else:
    print(f"Nie ma ucznia o imieniu {klucz}")

# 5. Iteracja (klucz + wartość)
for imie, punkty in uczniowie.items():
    print(f"{imie} -> {punkty}")

To jest esencja słowników. Tworzysz `{}`, dodajesz przez `[klucz] = wartosc`. Najważniejszy wzorzec maturalny to bezpieczne sprawdzanie `if klucz in slownik:`, aby uniknąć błędów.

Zadanie: Zliczanie wystąpień (klasyczny przykład)

Python
napis = "ala ma kota, kot ma ale"
zlicz_litery = {}

for litera in napis:
    if litera == ' ' or litera == ',':
        continue # Pomiń spacje i przecinki
    
    # Wzorzec na zliczanie:
    if litera in zlicz_litery:
        zlicz_litery[litera] += 1 # Jeśli już jest, zwiększ licznik
    else:
        zlicz_litery[litera] = 1 # Jeśli nie ma, stwórz klucz z wartością 1

print(zlicz_litery)
# Wynik: {'a': 4, 'l': 2, 'm': 2, 'k': 2, 'o': 2, 't': 2, 'e': 1}

To jest *najważniejszy* wzorzec użycia słownika na maturze. Iterujemy po danych. Sprawdzamy, czy klucz (tutaj 'litera') jest już w słowniku. Jeśli tak, zwiększamy jego wartość (licznik). Jeśli nie, tworzymy go z początkową wartością 1.

Mapa w C++ (std::map) - Podstawy i zliczanie

C++
#include <iostream>
#include <map>
#include <string>

using namespace std;

int main() {
    // 1. Tworzenie mapy (klucz: string, wartość: int)
    map<string, int> uczniowie;

    // 2. Dodawanie i modyfikacja
    uczniowie["Jan"] = 100;
    uczniowie["Anna"] = 95;
    uczniowie["Piotr"] = 80;
    uczniowie["Anna"] = 98; // Nadpisanie

    // 3. Odczyt (C++ automatycznie tworzy klucz!)
    // cout << uczniowie["Kasia"] << endl; // To jest pułapka! Stworzy "Kasia" z wartością 0.

    // 4. Bezpieczne sprawdzanie
    if (uczniowie.count("Kasia")) {
        cout << "Kasia ma " << uczniowie["Kasia"] << " pkt" << endl;
    } else {
        cout << "Nie ma ucznia o imieniu Kasia" << endl;
    }

    // 5. Wzorzec na zliczanie (prostszy niż w Pythonie!)
    string napis = "alamakota";
    map<char, int> zlicz_litery;
    for (char litera : napis) {
        zlicz_litery[litera]++; // Jeśli klucz 'litera' nie istnieje, C++ tworzy go z wart. 0 i OD RAZU zwiększa o 1.
    }

    // 6. Iteracja
    for (auto const& [klucz, wartosc] : zlicz_litery) {
        cout << klucz << ": " << wartosc << endl;
    }

    return 0;
}

W C++ `std::map` jest z biblioteki `<map>`. Jest jedna duża różnica: `mapa[klucz]++` działa *zawsze*, nawet jeśli klucza nie ma! Dzieje się tak, bo `mapa[klucz]` automatycznie tworzy nowy element z domyślną wartością (0 dla `int`), a dopiero potem `++` zwiększa ją do 1. To bardzo ułatwia zliczanie.

Przykładowe Zadania Maturalne

Matura 2026Zadanie Zadanie Typu Maturalnego 1

W pliku 'owoce.txt' znajduje się 1000 wierszy, z których każdy zawiera nazwę owocu (np. 'jablko', 'banan', 'jablko'). Napisz program, który policzy i wypisze, ile razy w pliku pojawiła się każda unikalna nazwa owocu. Posortuj wyniki alfabetycznie według nazw owoców.

Wskazówka: To jest klasyczne zadanie na zliczanie. Użyj słownika, gdzie kluczem będzie nazwa owocu (string), a wartością będzie liczba jego wystąpień (int). Iteruj po pliku i dla każdego owocu implementuj wzorzec 'sprawdź-czy-jest / zwiększ-licznik'.

Pokaż szkic rozwiązania
1. Stwórz pusty słownik: `licznik_owocow = {}`.
2. Otwórz plik 'owoce.txt' do odczytu.
3. Dla każdej linii w pliku:
   a. Wczytaj owoc: `owoc = linia.strip()`.
   b. Sprawdź, czy owoc jest w słowniku: `if owoc in licznik_owocow:`.
   c. Jeśli tak: `licznik_owocow[owoc] += 1`.
   d. Jeśli nie: `licznik_owocow[owoc] = 1`.
4. Po pętli, posortuj klucze słownika: `posortowane_owoce = sorted(licznik_owocow.keys())`.
5. W pętli po posortowanych kluczach, wypisz wynik:
   a. `for owoc in posortowane_owoce:`
   b. `  print(f"{owoc}: {licznik_owocow[owoc]}")`.
Matura 2025Zadanie 7.2 (Matura Maj 2025)

W bazie danych są tabele 'Laziki' (nr_lazika, nazwa) oraz 'Pomiary' (nr_lazika, data_pomiaru, ...). Podaj nazwę łazika, który wykonywał pomiary w najdłuższym okresie, licząc od pierwszego (najwcześniejszego) do ostatniego (najpóźniejszego) pomiaru. Podaj datę pierwszego i ostatniego pomiaru wykonanego przez ten łazik.

Wskazówka: To jest zadanie na grupowanie. Użyj słownika, aby przechować dane 'per łazik'. Kluczem będzie nr_lazika. Wartością może być lista, ale lepiej trzymać [min_data, max_data]. Iteruj po wszystkich pomiarach i na bieżąco aktualizuj min_data i max_data dla każdego łazika w słowniku.

Pokaż szkic rozwiązania
1. Wczytaj dane z 'Pomiary' i 'Laziki' (np. do dwóch list lub słownika nazw łazików).
2. Stwórz słownik do śledzenia dat: `daty_lazikow = {}`.
3. Iteruj po wszystkich pomiarach (każdy to `nr_lazika`, `data_pomiaru`):
   a. Sprawdź, czy łazik jest już w słowniku: `if nr_lazika in daty_lazikow:`
   b.    `stara_min_data = daty_lazikow[nr_lazika][0]`
   c.    `stara_max_data = daty_lazikow[nr_lazika][1]`
   d.    `daty_lazikow[nr_lazika][0] = min(stara_min_data, data_pomiaru)`
   e.    `daty_lazikow[nr_lazika][1] = max(stara_max_data, data_pomiaru)`
   f. Jeśli nie: `daty_lazikow[nr_lazika] = [data_pomiaru, data_pomiaru]`.
4. Po pętli, iteruj po słowniku `daty_lazikow`, aby znaleźć łazika z największą różnicą (max_data - min_data).

Częste Błędy

Błąd KeyError (Python)

Najczęstszy błąd. Próba odczytania klucza, który nie istnieje, np. print(slownik['klucz_ktorego_nie_ma']). Program się zatrzymuje.

Poprawka: Zawsze sprawdzaj, zanim odczytasz: if klucz in slownik: ... lub użyj bezpiecznej metody .get(): wartosc = slownik.get(klucz, 0).

Błędna logika zliczania

Uczeń od razu próbuje slownik[klucz] += 1. To zadziała tylko, jeśli klucz już tam jest. Jeśli nie, dostanie KeyError, bo próbuje dodać 1 do czegoś, co nie istnieje.

Poprawka: Użyj pełnego wzorca: if klucz in slownik: slownik[klucz] += 1 else: slownik[klucz] = 1. Albo prościej: slownik[klucz] = slownik.get(klucz, 0) + 1.

Użycie listy jako klucza (Python)

Klucze w słowniku Pythona muszą być niemutowalne (niezmienne). Próba slownik[[1, 2]] = 'lista' rzuci błąd TypeError: unhashable type: 'list'. Stringi, liczby i krotki (tuple) są OK.

Poprawka: Jeśli musisz użyć 'listy' jako klucza, zamień ją na krotkę (tuple): slownik[(1, 2)] = 'krotka'.

Mylenie iteracji po kluczach i wartościach

Piszesz for element in slownik: print(element) i oczekujesz wartości. Domyślnie pętla for w Pythonie iteruje po kluczach.

Poprawka: Jeśli chcesz wartości, pisz: for wartosc in slownik.values():. Jeśli chcesz oba, pisz: for klucz, wartosc in slownik.items():.

Kluczowe Wnioski

  • Słownik (mapa) przechowuje pary klucz-wartość.
  • Dostęp do wartości jest przez klucz, nie przez indeks (slownik['klucz']).
  • Jest to idealna struktura do zliczania wystąpień i grupowania danych.
  • W Pythonie (dict), odczyt i zapis są (średnio) O(1) - natychmiastowe.
  • W C++ (std::map), odczyt i zapis są O(log n) - bardzo szybkie.
  • W Pythonie, zawsze bezpiecznie sprawdzaj klucz (if klucz in slownik:) lub używaj .get(klucz, 0).
  • W C++, mapa[klucz]++ to prosty i bezpieczny sposób na zliczanie (automatycznie tworzy klucz z wartością 0, jeśli nie istnieje).

Najczęściej Zadawane Pytania

Jaka jest główna różnica między listą a słownikiem?

W liście odwołujesz się do elementów przez ich *numeryczną pozycję* (indeks), np. `lista[0]`. W słowniku odwołujesz się do elementów przez ich *unikalny klucz* (nazwę), np. `slownik['Anna']`. Poza tym lista jest uporządkowana, a słownik (przed Pythonem 3.7) nie gwarantował kolejności.

Kiedy używać słownika, a kiedy listy?

Użyj listy, gdy masz zbiór danych i ich kolejność jest ważna (np. wczytane dane z pliku, które chcesz posortować). Użyj słownika, gdy chcesz coś *zliczyć* lub *grupować* dane na podstawie jakiejś etykiety (np. 'ile razy wystąpiło każde słowo' lub 'jaka jest suma punktów dla 'Jana'').

Co się stanie, jak dodam element z kluczem, który już istnieje?

Nie zostanie dodany drugi element. Zamiast tego, *wartość* dla tego klucza zostanie *nadpisana* (zaktualizowana) nową wartością.

Jaka jest różnica między `map` a `unordered_map` w C++?

`map` (oparty na drzewach) gwarantuje złożoność O(log n) i przechowuje klucze *posortowane*. `unordered_map` (oparty na haszowaniu, jak `dict` w Pythonie) ma średnią złożoność O(1), ale nie przechowuje kluczy w żadnym określonym porządku. Na maturę oba są wystarczająco szybkie.

Jak w Pythonie iterować po kluczach i wartościach jednocześnie?

Użyj metody `.items()`. Jest to bardzo czytelne: `for klucz, wartosc in moj_slownik.items(): print(f"Klucz: {klucz}, Wartość: {wartosc}")`.

Chcesz opanować wszystkie tematy maturalne?

Dołącz do kursu i zyskaj dostęp do interaktywnych lekcji, edytora kodu i setek zadań.

Powiązane Tematy