Zadanie 1. Znaczki pocztowe

Pani Rekursywna ma kolekcję 300 znaczków. Każdy znaczek określony jest 6-cyfrową liczbą oznaczającą rok (cztery pierwsze cyfry od lewej strony) oraz miesiąc powstania (dwie cyfry z prawej strony) znaczka.

Przykładowe dane:

  • 201302

  • 201709

  • 201310

Pani Rekursywna chce znaleźć znaczki, które zostały wydrukowane w 2013 roku, oraz uporządkować je w kolejności od najnowszego do najstarszego.

Plik znaczki.txt zawiera 300 wierszy z oznaczeniami znaczków, które posiada pani Rekursywna. Każde oznaczenie zapisane jest w osobnej linii.

R1V878vRVYVTi

Przycisk umożliwiający pobranie pliku TXT z treścią zadania.

Plik TXT o rozmiarze 2.34 KB w języku polskim

Napisz program (w wybranym języku programowania), który znajdzie i uporządkuje poszukiwane kody znaczków od najnowszego do najstarszego, a następnie zapisze je w pliku znalezione.txt, każdy kod w osobnej linii.

Do oceny oddajesz:

  • plik znalezione.txt zawierający odpowiedź (uporządkowane od najnowszego do najstarszego kody znaczków, każdy kod zapisany w osobnej linii)

  • plik(i) z komputerową realizacją zadania (kodem programu)

Praca domowa

Przedstaw rozwiązanie zadania w postaci programu napisanego w wybranym języku programowania. Zadbaj o prawidłowe wczytanie i zapisanie danych z/do pliku tekstowego. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.

Rozwiązanie

Rozwiązanie zadania przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z wybranego języka programowania: C++, Java lub Python.

Do rozwiązania zadania potrzebna będzie tablica zawierająca znaczki wyprodukowane w 2013 roku. Następnie, w celu uporządkowania ich w kolejności od najnowszego do najstarszego, skorzystamy z dwóch algorytmów sortowania. Przyjmujemy indeksowanie tablic od 0, tak jak jest to reprezentowane w komputerze.

Pierwszym będzie sortowanie bąbelkowe, które ma dużą czasową złożoność obliczeniową O ( n 2 ) . Dokładne informacje na temat działania tego algorytmu znajdziesz w e‑materiale Sortowanie bąbelkoweDcy2OAkUuSortowanie bąbelkowe.

Drugim algorytmem, który przeanalizujemy, będzie sortowanie szybkie. Ma ono lepszą złożoność czasową: liniowo‑logarytmiczną O ( n log ( n ) ). Zagadnienie to zostało omówione w e‑materiale Sortowanie szybkieDXfvQGXppSortowanie szybkie.

Przykładowe rozwiązanie

Linia 1. Znaczki otwórz nawias kwadratowy 0 kropka kropka 299 zamknij nawias kwadratowy ← wczytaj dane z pliku cudzysłów znaczki kropka txt cudzysłów. Linia 2. liczbaZnaczków ← 300. Linia 4. Znaczki2013 otwórz nawias kwadratowy 0 kropka kropka 299 zamknij nawias kwadratowy. Linia 5. liczbaZnaczków2013 ← 0. Linia 7. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek liczbaZnaczków minus 1 wykonuj dwukropek. Linia 8. jeżeli Znaczki otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias ostrokątny 201300 oraz Znaczki otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny 201400 dwukropek. Linia 9. Znaczki2013 otwórz nawias kwadratowy liczbaZnaczków2013 zamknij nawias kwadratowy ← Znaczki otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 10. liczbaZnaczków2013 ← liczbaZnaczków2013 plus 1. Linia 12. sortowanie otwórz nawias okrągły Znaczki2013 przecinek liczbaZnaczków2013 zamknij nawias okrągły. Linia 14. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek liczbaZnaczków2013 minus 1 wykonuj dwukropek. Linia 15. zapisz Znaczki2013 otwórz nawias kwadratowy i zamknij nawias kwadratowy do pliku cudzysłów znalezione kropka txt cudzysłów.
  1. Główną część kodu rozpoczynamy od wczytania danych z pliku oraz zadeklarowania długości tablicy ze znaczkami. [linie kodu 1, 2]

  2. Następnie deklarujemy pustą tablicę przeznaczoną do przechowywania znaczków wydrukowanych w 2013 roku oraz zmienną, do której będziemy zapisywać liczbę tych znaczków. [linie kodu 4, 5]

  3. Kolejnym krokiem jest iteracja po wszystkich elementach tablicy Znaczki w celu odnalezienia tych, które zostały wyprodukowane w 2013 roku. Kiedy natrafimy na taki znaczek, zapisujemy go do tablicy Znaczki2013 na pierwszą wolną pozycję oraz zwiększamy zmienną liczbaZnaczków2013[linie kodu 7, 8, 9, 10]

  4. W tym momencie następuje wywołanie funkcji sortującej, której implementację omówimy, uwzględniając wybrany wariant sortowania.  [linia kodu 12]

  5. Ostatnim krokiem jest zapisanie posortowanych danych do pliku wynikowego. [linie kodu 14, 15]

Sortowanie bąbelkowe

Linia 1. sortowanieBąbelkowe otwórz nawias okrągły Znaczki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek długośćTablicy zamknij nawias okrągły. Linia 2. dla i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka długośćTablicy minus 1 przecinek wykonuj dwukropek. Linia 3. zamiana ← fałsz. Linia 4. dla j znak równości 1 przecinek 2 przecinek kropka kropka kropka długośćTablicy minus i minus 1 przecinek wykonuj dwukropek. Linia 5. jeżeli Znaczki otwórz nawias kwadratowy j minus 1 zamknij nawias kwadratowy zamknij nawias ostrokątny Znaczki otwórz nawias kwadratowy j zamknij nawias kwadratowy dwukropek. Linia 6. zamiana ← prawda. Linia 7. zamień Znaczki otwórz nawias kwadratowy j minus 1 zamknij nawias kwadratowy z Znaczki otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 8. jeżeli zamiana znak równości fałsz przerwij pętlę.
  1. Definiujemy funkcję sortowania bąbelkowego, która ułoży dane w tablicy w kolejności niemalejącej. [linia kodu 1]

  2. Inicjujemy pętlę, która pozwoli nam przejść po każdym indeksie komórki w tablicy tyle razy, ile wynosi długość tablicy. Definiujemy zmienną zamiana, która będzie przechowywać informację, czy w danej serii porównań nastąpiła zamiana. Liczba przejść po tablicy gwarantuje, że dla najgorszego przypadku (tablica posortowana odwrotnie do ustalonego porządku) wszystkie elementy znajdą się na odpowiednich pozycjach. W drugiej pętli pomijamy pierwszy indeks, ponieważ każda komórka sprawdzana jest z poprzednią (musimy zatem uważać, żeby nie wyjść poza zakres tablicy). [linie kodu 2, 3, 4]

  3. Sprawdzamy, czy następny element w tablicy nie jest większy od obecnie badanego. Jeżeli jest, zamieniamy ich kolejność oraz ustawiamy wartość zmiennej zamiana na prawdę. [linie kodu 6, 7]

  4. Jeżeli w poprzedniej serii porównań nie wystąpiła zamiana, oznacza to, że elementy są już posortowane i możemy przerwać działanie pętli. [linia kodu 8]

Sortowanie szybkie

Linia 1. sortowanieSzybkie otwórz nawias okrągły Znaczki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 2. jeżeli lewy otwórz nawias ostrokątny prawy. Linia 3. punktPodziału ← podział otwórz nawias okrągły Znaczki przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 4. sortowanieSzybkie otwórz nawias okrągły Znaczki przecinek lewy przecinek punktPodziału zamknij nawias okrągły. Linia 5. sortowanieSzybkie otwórz nawias okrągły Znaczki przecinek punktPodziału plus 1 przecinek prawy zamknij nawias okrągły.
  1. Definiujemy funkcję sortowania szybkiego, która będzie dzielić tablicę na części, a następnie sortować je osobno. [linia kodu 1]

  2. Sprawdzamy, czy tablica, na której chcemy dokonać podziału, nie jest jednoelementowa. [linia kodu 2]

  3. Wywołujemy funkcję, która wyznaczy punkt podziału tablic. [linia kodu 3]

  4. Inicjujemy rekurencyjnerekurencjarekurencyjne wywołanie funkcji dla utworzonych podtablic. [linie kodu 4, 5]

Linia 1. podział otwórz nawias okrągły Znaczki otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 2. punktPodziału ← Znaczki otwórz nawias kwadratowy prawy zamknij nawias kwadratowy. Linia 3. i ← lewy minus 1. Linia 4. j ← prawy plus 1. Linia 5. dopóki prawda wykonuj dwukropek. Linia 6. i ← i plus 1. Linia 7. dopóki Znaczki otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny punktPodziału wykonuj. Linia 8. i ← i plus 1. Linia 9. j ← j minus 1. Linia 10. dopóki Znaczki otwórz nawias kwadratowy j zamknij nawias kwadratowy zamknij nawias ostrokątny punktPodziału wykonuj dwukropek. Linia 11. j ← j minus 1. Linia 12. jeżeli i otwórz nawias ostrokątny j dwukropek. Linia 13. zamień Znaczki otwórz nawias kwadratowy i zamknij nawias kwadratowy z Znaczki otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 14. w przeciwnym razie dwukropek. Linia 15. zwróć j.
  1. Definiujemy funkcję, która wyznaczy element środkowy punktPodziału, a następnie ułoży dane według następującej zasady: punktPodziału na środku, równe lub mniejsze od punktPodziału po lewej stronie tablicy, większe od punktPodziału po prawej stronie tablicy. [linia kodu 1]

  2. Wybieramy element środkowy (na przykład ostatni). Następnie w zmiennych i oraz j zapisujemy miejsca przed pierwszym oraz za ostatnim elementem tablicy, którą chcemy posortować. [linie kodu 2, 3, 4]

  3. Zwiększamy indeks i, do momentu znalezienia elementu tablicy większego niż punktPodziału. Indeks j zmniejszamy, aby w końcu znaleźć element mniejszy od punktPodziału. [linie kodu od 6 do 11]

  4. Po znalezieniu mniejszego elementu zmieniamy te elementy, aby uzyskać w podtablicach odpowiednie wartości. [linie kodu 12, 13]

  5. Powtarzamy dwa powyższe punkty do momentu, gdy i osiągnie wartość większą lub równą j. Wtedy zwracamy j, czyli punkt podziału tablicy. [linie kodu 14, 15]

Odpowiedź do zadania

Prawidłowe wyniki dla danych z pliku:

R1I7tBrcjgNzd

Przycisk umożliwiający pobranie pliku TXT z odpowiedzią do zadania.

znalezione.txt
Plik TXT o rozmiarze 55.00 B w języku polskim

Słownik

czasowa złożoność obliczeniowa algorytmu
czasowa złożoność obliczeniowa algorytmu

określenie liczby operacji wymaganych do wykonania danego algorytmu; zależy od danych wejściowych

pamięciowa złożoność obliczeniowa algorytmu
pamięciowa złożoność obliczeniowa algorytmu

określenie ilości pamięci operacyjnej wymaganej do wykonania danego algorytmu; zależna od danych wejściowych

rekurencja
rekurencja

technika programowania, w której funkcja wywołuje samą siebie, aż do napotkania przypadku podstawowego, czyli takiego, którego nie da się rozłożyć na mniejsze problemy