Algorytm sortowania pozycyjnego słów

Sortowanie pozycyjne polega na ustaleniu kolejności słów według pozycji występujących w nich kolejnych liter.

Działanie sortowania pozycyjnego opiera się na porównywaniu słów względem znaków w ciągu, gdzie i‑ty znak słowa jest zawsze porównywany z i‑tym znakiem innego słowa.

Po ustaleniu, według której pozycji liter nastąpi sortowanie, słowa są ustawiane w odpowiedniej kolejności za pomocą dowolnego stabilnego algorytmu sortowania (jak sortowanie bąbelkowe, przez wstawianie, przez zliczanie).

Jeżeli słowo A jest sufiksem słowa B i słowo B jest dłuższe, to słowo A jest mniejsze w porządku leksykograficznym.

Jes to równoznaczne z: AAB < AABA

Przykład 1

Przed sortowaniem:

  • ACA,

  • ACAB,

  • AAB.

Po sortowaniu:

  • AAB,

  • ACA,

  • ACAB.

Złożoność obliczeniowa algorytmu wynosi O(d(n + k)), gdzie d oznacza liczbę znaków w słowach, n – liczbę słów, natomiast k – liczbę znaków, z których dane słowa się składają.

Powyższa złożoność obliczeniowa oznacza, że dla małego zakresu różnych znaków algorytm sortowania pozycyjnego jest efektywniejszy niż algorytmy bardziej złożone, stosujące metodę „dziel i zwyciężaj”, których średnia złożoność obliczeniowa wynosi O(nlogn).

Aby posortować słowa, trzeba ustalić, w jakim porządku powinny być one zapisywane. Uniwersalnym wyborem jest porządek leksykograficznyporządek leksykograficznyporządek leksykograficzny, stosowany powszechnie w słownikach, encyklopediach, indeksach itp.

Zadanie 1. Herbaciarnia

W herbaciarni „Kompilator” stale powstają nowe mieszanki herbaty.

Pan Proceduralny zajmuje się przygotowywaniem odpowiednich kompozycji z suszonych liści oraz aromatycznych dodatków.

Ma on tajemny sposób na przechowywanie składników – trzyma je w kolejności leksykograficznej według trzech ostatnich liter każdego słowa.

Zadanie 1.1

Ktoś zamienił miejscami słoiki, przez co Pan Proceduralny nie może przygotować mieszanki według powierzonego mu przepisu.

Napisz program, który wypisze kolejność, w jakiej powinny znajdować się słoiki ze składnikami. Wyniki zapisz do pliku wyniki.txt.

Plik Lista składników.txt zawiera 28 nazw składników wykorzystywanych w herbaciarni, każda zapisana jest w nowej linii.

Lista składników.txt

RyBEaZNaRrmaU

Plik tekstowy do pobrania zawiera listę skróconych nazw składników.

Plik TXT o rozmiarze 198.00 B w języku polskim

Fragment przykładowych danych:

Linia 1. MATCH. Linia 2. OOLON. Linia 3. SENCH.

Do oceny oddajesz:

  • plik wynik.txt zawierający odpowiedź (nazwy składników uporządkowane w kolejności leksykograficznej według trzech ostatnich liter każdego słowa)

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

Praca domowa

Korzystając z przedstawionego niżej pseudokodu, napisz program (w języku C++, Java lub Python), który posortuje alfabetycznie listę składników według trzech ostatnich liter. Zadbaj o prawidłowe wczytanie danych z pliku tekstowego. Rozwiązanie zadania znajdziesz w osobnym pliku tekstowym, pod omówieniem pseudokodu.

Rozwiązanie

Rozwiązanie przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można posługiwać się językami C++, Java lub Python.

Ważne!

Pamiętaj o uwzględnieniu sortowanej pozycji w wybranym algorytmie sortowania.

Linia 1. pozycja znak równości długośćCiąguZnaków minus 1. Linia 2. pozycjaKońcowa znak równości długośćCiąguZnaków minus 3. Linia 3. dopóki pozycja zamknij nawias ostrokątny znak równości pozycjaKońcowa wykonuj dwukropek. Linia 4. sortuj otwórz nawias okrągły lista otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek długośćListy przecinek pozycja zamknij nawias okrągły. Linia 5. pozycja znak równości pozycja minus 1. Linia 6. wypisz lista do pliku.
  1. Zapisujemy pierwszą pozycję (literę), którą będziemy sprawdzać. Z kolei do zmiennej pozycjaKońcowa zapisujemy indeks pozycji, na której zaczyna się podciąg, który bierze udział w sortowaniu. [linia 1]

  2. Tworzymy pętlę. Zapisane wewnątrz niej instrukcje będą wykonywane dopóty, dopóki nie zostanie przekroczona długość podciągu, według którego chcemy dokonać sortowania ciągu znaków opisującego składnik mieszanki. [linia 3]

  3. Sortujemy listę składników, biorąc pod uwagę literę na odpowiedniej pozycji. Następnie dekrementujemydekrementacjadekrementujemy zmienną, w której zapisana jest obecna pozycja, aby użyć jej w następnym cyklu pętli. [linie 4, 5]

  4. Wypisujemy posortowaną listę składników. [linia 6]

W podanym pseudokodzie pojawiła się funkcja sortuj(). Zdefiniujemy ją, wykorzystując algorytm sortowania przez zliczanie, o którym więcej informacji znajdziesz w e‑materiale Sortowanie przez zliczaniePNx8quWZlSortowanie przez zliczanie.

Linia 1. funkcja sortuj otwórz nawias okrągły lista przecinek długośćListy przecinek pozycja zamknij nawias okrągły. Linia 2. lista2 otwórz nawias kwadratowy długośćListy zamknij nawias kwadratowy. Linia 3. liczbaZnakówWAlfabecie znak równości 26. Linia 4. pomocnicza otwórz nawias kwadratowy liczbaZnakówWAlfabecie zamknij nawias kwadratowy. Linia 5. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy minus 1 wykonuj dwukropek. Linia 6. pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości 0. Linia 7. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy minus 1 wykonuj dwukropek. Linia 8. pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy plus 1. Linia 9. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka liczbaZnakówWAlfabecie minus 1 wykonuj dwukropek. Linia 10. pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy plus pomocnicza otwórz nawias kwadratowy i minus 1 zamknij nawias kwadratowy. Linia 11. dla i znak równości długośćListy minus 1 przecinek długośćListy minus 2 przecinek kropka kropka kropka 0 wykonuj dwukropek. Linia 12. lista2 otwórz nawias kwadratowy pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy zamknij nawias kwadratowy znak równości lista otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 13. pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy minus 1. Linia 14. lista znak równości lista2.
  1. Deklarujemy funkcję, która będzie sortować znaki znajdujące się na ustalonej wcześniej pozycji. [linia 1]

  2. Do tablicy pomocniczej wpisujemy same zera. Jest to konieczne do późniejszego zliczania znaków. [linia 4, 5, 6]

  3. Tworzymy pętlę. W każdym jej cyklu zliczone zostaną elementy należące do wybranego zakresu. Ponieważ sortujemy słowa, zakresem będzie lista znaków w alfabecie (policzymy wystąpienia liter A, B, C itd.). Rezultaty zapiszemy, zwiększając wartości o do której interesuje nas sortowanie odpowiednich komórekkomórka tablicykomórek w tablicy pomocniczej. Od wartości znaku (zapisanej jako odpowiadający mu kod ASCIIkod ASCIIkod ASCII) odejmujemy wartość liczbową odpowiadającą znakowi A. [linie 7, 8]

  4. Zmieniamy sposób zapisywania danych w tablicy pomocniczej. Zamiast liczby wystąpień litery znajdującej się na odpowiedniej pozycji w alfabecie, komórka będzie zawierać również liczbę znaków, które znajdują się na wcześniejszej pozycji. W celu wprowadzenia zmian dodajemy do wartości komórki w tablicy pomocniczej wartość zapisaną w poprzedniej komórce. [linie 9, 10]

  5. Tworzymy listę zawierającą znaki na pozycjach, które określa tablica pomocnicza. Po umieszczeniu znaku na odpowiedniej pozycji dekrementujemydekrementacjadekrementujemy wartość w tablicy pomocniczej (jeśli tego nie zrobimy, sortowanie nie zadziała dla znaków, które pojawiają się więcej niż jeden raz). [linie 11, 12, 13]

  6. Umieszczamy posortowaną tablicę w liście wynikowej, czym kończymy pojedynczy cykl sortowania. [linia 14]

Odpowiedź

Odpowiedź do zadania dla danych zapisanych w pliku Lista składników.txt:

R125f4xpbspqb

Plik txt zawierający listę składników.

Plik TXT o rozmiarze 168.00 B w języku polskim

Zadanie 1.2

Po dodaniu dwóch nowych składników właściciel herbaciarni zauważył, że najczęściej używane składniki znajdują się na końcu magazynu. Ustalono więc, że słoiki ze składnikami powinny być ustawione w odwrotnym porządku alfabetycznym – wciąż jednak uwzględniając jedynie trzy ostatnie litery każdego słowa. Poproszono również, aby dla ułatwienia zapisać numery miejsc nowych składników wraz z ich nazwami.

Na jakich pozycjach powinny się znaleźć nowe składniki?

Korzystając z wybranego języka, napisz program, który posortuje dane w odwrotnej kolejności alfabetycznej, a następnie wypisze numery pozycji dwóch nowych składników oraz ich nazwy (znajdują się one na dwóch ostatnich pozycjach na liście). Wyniki zapisz do pliku wyniki.txt.

Plik Lista składników.txt zawiera 28 nazw składników wykorzystywanych w herbaciarni, każda zapisana jest w nowej linii.

RMyFuptBOezkL

Plik txt zawierający listę składników.

Plik TXT o rozmiarze 212.00 B w języku polskim

Fragment przykładowych danych:

Linia 1. PUERH. Linia 2. MATCH. Linia 3. OOLON. Linia 4. SENCH. Linia 5. PEKOE.

Do oceny oddajesz:

  • plik wynik.txt zawierający odpowiedź (nazwy składników uporządkowane w odwrotnej kolejności leksykograficznej według trzech ostatnich liter każdego słowa; powinien również zawierać oddzielone pojedynczą pustą linią od posortowanej listy nazwy wyróżnionych składników wraz z pozycjami)

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

Praca domowa

Rozwiąż zadanie, tworząc program w języku C++, Java lub Python. Zadbaj o prawidłowe wczytanie danych z pliku tekstowego. Rozwiązanie zadania znajdziesz w osobnym pliku tekstowym pod omówieniem pseudokodu.

Rozwiązanie

Rozwiązanie przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można posługiwać się językami C++, Java lub Python.

Skorzystajmy z nieco zmodyfikowanego kodu z podpunktu 1. i zapiszmy przed sortowaniem słowa, których pozycję należy podać jako rozwiązanie zadania.

Podobnie jak w podpunkcie 1., do uporządkowania zbioru wykorzystamy algorytm sortowania przez zliczanie.

Algorytm ten nie jest jednak przystosowany do użycia w celu porządkowania zbioru słów w kolejności odwrotnej od alfabetycznej. Aby znaki zostały umieszczone na właściwych pozycjach, musimy w ostatnim kroku [linia 9] zmodyfikować sposób uzupełniania listy wynikowej o tablicę posortowaną.

Na końcu należy znaleźć nowe nazwy i podać je wraz z numerami pozycji na liście.

Linia 1. szukaneSłowa otwórz nawias kwadratowy 0 zamknij nawias kwadratowy znak równości lista otwórz nawias kwadratowy 28 zamknij nawias kwadratowy. Linia 2. szukaneSłowa otwórz nawias kwadratowy 1 zamknij nawias kwadratowy znak równości lista otwórz nawias kwadratowy 29 zamknij nawias kwadratowy. Linia 4. pozycja znak równości długośćCiąguZnaków minus 1. Linia 5. pozycjaKońcowa znak równości długośćCiąguZnaków minus 3. Linia 6. dopóki pozycja zamknij nawias ostrokątny znak równości pozycjaKońcowa wykonuj dwukropek. Linia 7. sortuj otwórz nawias okrągły lista otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek długośćListy przecinek pozycja zamknij nawias okrągły. Linia 8. pozycja znak równości pozycja minus 1. Linia 10. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy wykonuj dwukropek. Linia 11. jeżeli lista otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości znak równości szukaneSłowa otwórz nawias kwadratowy 0 zamknij nawias kwadratowy wykonaj dwukropek. Linia 12. pozycja otwórz nawias kwadratowy 0 zamknij nawias kwadratowy znak równości i. Linia 13. jeżeli lista otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości znak równości szukaneSłowa otwórz nawias kwadratowy 1 zamknij nawias kwadratowy wykonaj dwukropek. Linia 14. pozycja otwórz nawias kwadratowy 1 zamknij nawias kwadratowy znak równości i. Linia 16. wypisz lista do pliku. Linia 17. wypisz pustą linię do pliku. Linia 18. wypisz szukaneSłowa otwórz nawias kwadratowy 0 zamknij nawias kwadratowy pozycja otwórz nawias kwadratowy 0 zamknij nawias kwadratowy do pliku. Linia 19. wypisz szukaneSłowa otwórz nawias kwadratowy 1 zamknij nawias kwadratowy pozycja otwórz nawias kwadratowy 1 zamknij nawias kwadratowy do pliku.
  • Zapisujemy nazwy szukanych składników [linie 1, 2]. Przeszukujemy listę, aby znaleźć pozycje szukanych słów [linie od 10 do 14].

  • Wypisujemy nazwy nowych składników wraz z ich pozycjami na liście [linie od 16 do 19].

Linia 1. funkcja sortuj otwórz nawias okrągły lista przecinek długośćListy przecinek pozycja zamknij nawias okrągły. Linia 2. lista2 otwórz nawias kwadratowy długośćListy zamknij nawias kwadratowy. Linia 3. liczbaZnakówWAlfabecie znak równości 26. Linia 4. pomocnicza otwórz nawias kwadratowy liczbaZnakówWAlfabecie zamknij nawias kwadratowy. Linia 5. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy minus 1 wykonuj dwukropek. Linia 6. pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości 0. Linia 7. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy minus 1 wykonuj dwukropek. Linia 8. pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy plus 1. Linia 9. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka liczbaZnakówWAlfabecie minus 1 wykonuj dwukropek. Linia 10. pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy plus pomocnicza otwórz nawias kwadratowy i minus 1 zamknij nawias kwadratowy. Linia 11. dla i znak równości długośćListy minus 1 przecinek długośćListy minus 2 przecinek kropka kropka kropka 0 wykonuj dwukropek. Linia 12. lista2 otwórz nawias kwadratowy pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy zamknij nawias kwadratowy znak równości lista otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 13. pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy znak równości pomocnicza otwórz nawias kwadratowy kodASCII otwórz nawias okrągły lista otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias kwadratowy pozycja zamknij nawias kwadratowy zamknij nawias okrągły minus kodASCII otwórz nawias okrągły A zamknij nawias okrągły zamknij nawias kwadratowy minus 1. Linia 14. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka długośćListy minus 1 wykonuj dwukropek. Linia 15. lista otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości lista2 otwórz nawias kwadratowy długośćListy minus i minus 1 zamknij nawias kwadratowy.
  • Uruchamiamy pętlę, w której będziemy odwracać kolejność słów zapisanych na posortowanej liście (ostatnie słowo trafi teraz na pierwszą pozycję, przedostatnie na drugą itd.) [linie 14, 15].

Komentarz do zadania

Rozwiązując przedstawione zadania, możesz użyć innego algorytmu sortowania. Musisz jednak pamiętać, aby zastosować stabilny algorytm sortowaniastabilność algorytmu sortowaniastabilny algorytm sortowania.

Odpowiedź

Odpowiedź do zadania dla danych zapisanych w pliku Lista składników.txt:

R12MDskNQVWIF

Plik txt zawierający listę składników.

Plik TXT o rozmiarze 199.00 B w języku polskim

Słownik

dekrementacja
dekrementacja

zmniejszenie wartości zmiennej o jeden

inkrementacja
inkrementacja

zwiększenie wartości zmiennej o jeden

iteracja pętli
iteracja pętli

inaczej: cykl pętli, obieg pętli; pojedyncze wykonanie instrukcji zapisanych w pętli

kod ASCII
kod ASCII

system kodowania znaków (cyfr, liter, znaków interpunkcyjnych, sterujących, specjalnych i innych), w którym każdemu symbolowi przyporządkowana jest pewna wartość liczbowa

komórka tablicy
komórka tablicy

miejsce przeznaczone do przechowywania pojedynczego elementu tablicy

porządek leksykograficzny
porządek leksykograficzny

„słownikowy” sposób porządkowania słów opierający się na dwóch zasadach:

  1. porównując słowa, sprawdzamy kolejne znaki w słowach do momentu, aż napotkamy różne znaki – wtedy „mniejsze” co do wartości jest to słowo, którego znak stoi bliżej litery A w alfabecie;

  2. jeżeli po sprawdzeniu wszystkich znaków jednego ze słów nadal nie znaleźliśmy różnicy, to słowo krótsze jest „mniejsze” co do wartości; natomiast dwa jednakowe słowa mają taką samą wartość

stabilność algorytmu sortowania
stabilność algorytmu sortowania

cecha algorytmu sortowania polegająca na tym, że w przypadku napotkania dwóch identycznych elementów nie zmienia się ich kolejność na posortowanej liście; po posortowaniu ciągów BB, AB, BA, AA z uwzględnieniem pierwszego znaku i z zastosowaniem algorytmu stabilnego otrzymamy kolejność: AB, AA, BB, BA