Tablice Jednowymiarowe (Listy) na Maturze z Informatyki
Tablica jednowymiarowa to najważniejsza struktura danych, jaką musisz znać. Wyobraź ją sobie jako listę zakupów lub szafkę z ponumerowanymi szufladami. Zamiast tworzyć sto zmiennych `liczba1`, `liczba2`, `liczba3`... tworzysz jedną 'szafkę' (tablicę) o nazwie `liczby` i przechowujesz w niej wartości w 'szufladach' o numerach (indeksach) 0, 1, 2... W Pythonie najczęściej będziesz używać `listy`, która jest bardzo elastyczną wersją tablicy. W C++ masz do wyboru statyczne tablice `int tab[100]` lub (co polecamy) dynamiczne `wektory` (`vector<int>`), które działają jak listy w Pythonie. Na maturze *każde* zadanie polegające na wczytaniu danych z pliku i ich późniejszym przetwarzaniu (np. sortowaniu, szukaniu min/max, analizowaniu sąsiadów) będzie wymagało użycia tablicy.
Dlaczego to ważne? Nie da się zdać matury z informatyki bez tablic. Służą do wczytania wszystkich danych z pliku, do przechowywania wyników pośrednich, do budowania sita Eratostenesa, do przechowywania stanów w algorytmach dynamicznych. Każde zadanie z plikiem tekstowym (np. `liczby.txt`, `dane.txt`) w praktyce wymaga wczytania tych danych do tablicy, a dopiero potem ich przetworzenia.
Teoria
Tablica jednowymiarowa (lista) to struktura przechowująca kolekcję elementów (np. liczb, napisów) w określonej kolejności. Kluczową cechą jest dostęp do każdego elementu poprzez jego *indeks* (numer 'szuflady'). Dostęp do elementu po indeksie jest natychmiastowy (złożoność O(1)).
Jak to działa?
- Krok 1: Indeksowanie od ZERA. To najważniejsza zasada. Pierwszy element tablicy ma zawsze indeks 0, drugi ma indeks 1, i tak dalej.
- Krok 2: Ostatni element w tablicy o rozmiarze 'n' ma zawsze indeks 'n-1'.
- Krok 3: Deklaracja (Python): Tworzysz pustą listę 'dane = []' i dodajesz elementy 'dane.append(x)' lub tworzysz listę od razu 'dane = [1, 2, 3]'.
- Krok 4: Deklaracja (C++): Polecamy 'vector<int> dane;' i dodawanie 'dane.push_back(x)'. Można też użyć statycznej 'int dane[100];' jeśli znasz rozmiar.
- Krok 5: Dostęp: Aby odczytać wartość, używasz nawiasów kwadratowych: 'zmienna = dane[5]' (pobierze szósty element).
- Krok 6: Modyfikacja: Aby zmienić wartość, robisz to samo: 'dane[5] = 100' (zmieni szósty element na 100).
- Krok 7: Iteracja: Najczęściej po tablicy przechodzisz pętlą 'for', albo po elementach ('for element in dane:') albo po indeksach ('for i in range(len(dane)):').
Złożoność: Złożoność czasowa: Odczyt lub zapis elementu na konkretnym indeksie (np. `dane[5] = 10`) jest natychmiastowy i ma złożoność O(1). Przeszukanie tablicy (znalezienie wartości): O(n). Dodanie elementu na koniec (Python `append`, C++ `push_back`): O(1) (amortyzowane).
Implementacja
Listy w Pythonie (tworzenie, dodawanie, iteracja)
Python# 1. Tworzenie pustej listy i dodawanie
liczby = []
liczby.append(10)
liczby.append(20)
liczby.append(30)
# teraz liczby to [10, 20, 30]
# 2. Dostęp i modyfikacja (indeksy 0, 1, 2)
print(f"Pierwszy element: {liczby[0]}") # 10
liczby[1] = 99 # Zmiana 20 na 99
# teraz liczby to [10, 99, 30]
# 3. Iteracja po elementach
for x in liczby:
print(x * 2)
# Wynik: 20, 198, 60
# 4. Iteracja po indeksach (gdy potrzebujesz i)
for i in range(len(liczby)):
print(f"Indeks {i} ma wartosc {liczby[i]}")
# 5. Wczytanie wszystkich liczb z pliku do listy
dane_z_pliku = []
with open('dane.txt') as f:
for linia in f:
dane_z_pliku.append(int(linia.strip()))
# teraz masz wszystkie liczby w liście 'dane_z_pliku'W Pythonie używamy `list`. Są dynamiczne (same się powiększają). `append()` dodaje na koniec. `len(lista)` zwraca liczbę elementów. Wczytanie pliku do listy to najczęstszy schemat maturalny.
Wektory w C++ (vector) - zalecana metoda
C++#include <iostream>
#include <vector> // Musisz zaimportować wektory
using namespace std;
int main() {
// 1. Tworzenie pustego wektora i dodawanie
vector<int> liczby;
liczby.push_back(10);
liczby.push_back(20);
liczby.push_back(30);
// teraz liczby to {10, 20, 30}
// 2. Dostęp i modyfikacja (indeksy 0, 1, 2)
cout << "Pierwszy element: " << liczby[0] << endl; // 10
liczby[1] = 99; // Zmiana 20 na 99
// teraz liczby to {10, 99, 30}
// 3. Iteracja po elementach (C++11 i nowsze)
for (int x : liczby) {
cout << x * 2 << endl;
}
// Wynik: 20, 198, 60
// 4. Iteracja po indeksach
for (int i = 0; i < liczby.size(); i++) {
cout << "Indeks " << i << " ma wartosc " << liczby[i] << endl;
}
return 0;
}`vector` to 'inteligentna tablica' w C++. Działa jak lista w Pythonie. `#include <vector>` jest konieczne. `push_back()` dodaje na koniec, a `size()` zwraca liczbę elementów.
Tablice statyczne w C++ (stara metoda)
C++#include <iostream>
using namespace std;
int main() {
// 1. Deklaracja tablicy o stałym rozmiarze
const int ROZMIAR = 100;
int liczby[ROZMIAR];
int n = 0; // Licznik, ile elementów faktycznie wczytaliśmy
// 2. Wypełnianie (np. 3 elementami)
liczby[0] = 10;
liczby[1] = 20;
liczby[2] = 30;
n = 3;
// 3. Dostęp i modyfikacja
cout << "Pierwszy element: " << liczby[0] << endl; // 10
liczby[1] = 99; // Zmiana 20 na 99
// 4. Iteracja (musimy znać 'n' - liczbę elementów!)
for (int i = 0; i < n; i++) {
cout << "Indeks " << i << " ma wartosc " << liczby[i] << endl;
}
return 0;
}Tablice statyczne `int nazwa[rozmiar]` mają stały, niezmienny rozmiar. Są mniej elastyczne niż wektory, bo musisz z góry znać maksymalny rozmiar. Użyteczne np. w Sicie Eratostenesa, gdzie robisz `bool sito[1000001]`.
Przykładowe Zadania Maturalne
W pliku 'dane.txt' znajduje się 100 liczb całkowitych, każda w osobnym wierszu. Napisz program, który wczyta wszystkie liczby, a następnie wypisze je w odwrotnej kolejności (od ostatniej wczytanej do pierwszej).
Wskazówka: Nie da się tego zrobić bez zapisania liczb. Musisz wczytać wszystkie liczby z pliku do tablicy (listy). Dopiero po wczytaniu całego pliku, zrób drugą pętlę, która iteruje po tablicy od końca do początku.
Pokaż szkic rozwiązania
1. Stwórz pustą listę (lub wektor) 'liczby = []'. 2. Otwórz plik 'dane.txt' do odczytu. 3. W pętli FOR wczytaj każdą linię z pliku. 4. W pętli, konwertuj linię na int i dodaj do listy: 'liczby.append(int(linia.strip()))'. 5. Po zamknięciu pliku, rozpocznij nową pętlę FOR iterującą *wstecz*. a. Python: 'for i in range(len(liczby) - 1, -1, -1):'. b. C++: 'for (int i = liczby.size() - 1; i >= 0; i--)'. 6. W pętli wstecznej wypisz element: 'print(liczby[i])'.
Plik pi.txt zawiera 10 000 cyfr po przecinku, każda w osobnym wierszu. Fragmentem 2-cyfrowym nazywamy dwie następujące po sobie cyfry w pliku pi.txt (np. cyfra z wiersza 1 i 2, 2 i 3 itd.). Znajdź liczbę wszystkich fragmentów 2-cyfrowych, które są zapisami dziesiętnymi liczb o wartościach większych od 90.
Wskazówka: Aby móc analizować 'sąsiadujące' cyfry, musisz najpierw wczytać je wszystkie do jednej, dużej tablicy (listy). Dopiero wtedy możesz iterować po tej tablicy pętlą 'for i in range(len(tablica) - 1)' i patrzeć na element 'tablica[i]' oraz następny 'tablica[i+1]'.
Pokaż szkic rozwiązania
1. Stwórz pustą listę (lub wektor) 'cyfry = []'. 2. Otwórz plik 'pi.txt' do odczytu. 3. W pętli FOR wczytaj każdą linię z pliku i dodaj do listy: 'cyfry.append(int(linia.strip()))'. 4. Zainicjuj 'licznik_90 = 0'. 5. Rozpocznij pętlę po *indeksach* tablicy, ale do przedostatniego elementu: a. Python: 'for i in range(len(cyfry) - 1):'. b. C++: 'for (int i = 0; i < cyfry.size() - 1; i++)'. 6. W pętli pobierz bieżącą i następną cyfrę: 'c1 = cyfry[i]', 'c2 = cyfry[i+1]'. 7. Oblicz wartość fragmentu: 'fragment_wartosc = c1 * 10 + c2'. 8. Sprawdź warunek: 'if fragment_wartosc > 90:'. 9. Jeśli tak, zwiększ licznik: 'licznik_90 += 1'. 10. Po pętli wypisz 'licznik_90'.
Częste Błędy
❌ Błąd 'IndexError: list index out of range'
Najczęstszy błąd na maturze. Dzieje się, gdy próbujesz odwołać się do indeksu, który nie istnieje, np. 'tablica[n]' (gdzie 'n' to długość tablicy). Prawidłowy ostatni indeks to 'n-1'. Często zdarza się w pętlach, gdy sprawdzasz 'tablica[i+1]' a pętla idzie do końca.
Poprawka: Pamiętaj, że ostatni indeks to `len(tab) - 1`. Jeśli w pętli odwołujesz się do `tab[i+1]`, pętla musi kończyć się na `len(tab) - 2` (czyli `range(len(tab) - 1)`).
❌ Mylenie `len()` z ostatnim indeksem
Jeśli 'len(tab)' wynosi 10 (jest 10 elementów), to ostatni element ma indeks 9. Pisanie 'for i in range(len(tab))' jest OK, ale 'tab[len(tab)]' to błąd.
Poprawka: Zawsze pamiętaj: 'len' to liczba elementów, 'len - 1' to ostatni indeks.
❌ Python: Zmiana listy przez referencję
Piszesz `lista2 = lista1`. Myślisz, że masz kopię. Zmieniasz `lista2` i nagle psuje Ci się `lista1`. To dlatego, że obie zmienne wskazują na *tę samą* listę w pamięci.
Poprawka: Aby zrobić prawdziwą kopię, użyj: `lista2 = lista1.copy()` lub `lista2 = lista1[:]`.
❌ C++: Używanie tablicy statycznej dla danych z pliku
Deklarujesz 'int dane[100];' a w pliku jest 2000 liczb. Program się wysypie lub nadpisze pamięć. Albo deklarujesz 'int dane[5000];' 'na zapas', co marnuje pamięć.
Poprawka: W C++ do wczytywania danych z pliku (gdy nie znasz dokładnej liczby) zawsze używaj 'vector'. Jest dynamiczny, bezpieczny i tak samo szybki w dostępie.
Kluczowe Wnioski
- Tablica (lista/wektor) to pojemnik na wiele wartości, np. wczytanych z pliku.
- Indeksowanie ZAWSZE zaczyna się od 0.
- Ostatni element tablicy 'tab' o długości 'n' ma indeks 'n-1'.
- W Pythonie używaj 'list' (są dynamiczne, 'append()' dodaje na koniec).
- W C++ preferuj 'vector' (dynamiczny, 'push_back()' dodaje na koniec) nad statycznymi tablicami.
- Dostęp po indeksie 'tab[i]' jest super szybki (złożoność O(1)).
- Wczytując plik, najpierw wrzuć dane do tablicy, a dopiero potem je przetwarzaj.
Najczęściej Zadawane Pytania
❓ Jaka jest różnica między tablicą a listą?
Technicznie, 'tablica' (array) ma stały rozmiar i przechowuje elementy tego samego typu. 'Lista' (list) jest dynamiczna (może rosnąć i maleć). W Pythonie, to, czego używasz (`lista = []`), nazywa się `list` i jest dynamiczne. W C++, `int tab[100]` to tablica, a `vector<int> v` to dynamiczna 'lista'. Na maturze te pojęcia często używane są zamiennie.
❓ C++: Kiedy `vector` a kiedy `int tab[]`?
Prosta zasada: do wczytywania danych z pliku *zawsze* używaj `vector`. Do algorytmów, gdzie z góry wiesz, jak dużej tablicy potrzebujesz (np. sito do 1 000 000), możesz użyć statycznej tablicy `bool sito[1000001]`, bo jest minimalnie szybsza w inicjalizacji.
❓ Jak szybko znaleźć ostatni element?
W Pythonie masz skrót: `ostatni = lista[-1]`. W C++ musisz użyć rozmiaru: `int ostatni = wektor[wektor.size() - 1];`.
❓ Dlaczego `len(lista)` to 5, ale ostatni indeks to 4?
Bo indeksy liczymy od zera! Pięć elementów ma indeksy: 0, 1, 2, 3, 4. To jest 5 liczb, ale ostatnia to 4. To najważniejsza koncepcja do zapamiętania.
❓ Jak wczytać linię z dwiema liczbami do tablicy?
W Pythonie: `lista_par = []`. W pętli: `a, b = map(int, linia.split())` i dodajesz do listy np. krotkę: `lista_par.append((a, b))`.
Chcesz opanować wszystkie tematy maturalne?
Dołącz do kursu i zyskaj dostęp do interaktywnych lekcji, edytora kodu i setek zadań.