matematykaszkolna.pl
Sortowanie plików Mariusz: Sortowanie plików Na wikipedii podali że najlepiej nadaje się do tego sortowanie przez scalanie lub jakaś hybryda z wczytywaniem fragmentów pliku do pamięci, sortowanie w pamięci ulubionym algorytmem (tutaj chcałbym zauważyć że quicksort is not always so quick) a następnie z scalaniem fragmentów Przypuśćmy że chcemy posortować linie w pliku przez scalanie Ograniczeniem jest to że nie znamy liczby linii w pliku (przeczytanie pliku aby poznać liczbę linii nie jest rozwiązaniem bo może nie zmieścić się w zakresie typu int )
19 lut 20:02
TC: emotkaemotkaemotkaemotkaemotkaemotkaemotkaemotka "przeczytanie pliku aby poznać liczbę linii nie jest rozwiązaniem" emotka emotka emotkaemotkaemotkaemotkaemotkaemotka słyszałeś o tablicach?
19 lut 20:26
Mariusz: 1. Tablica nie jest przystosowana do dostępu sekwencyjnego 2. Co gdy zawartość pliku nie zmieści się w pamięci ?
19 lut 20:34
jc: @Mariusz. Tak, jak piszesz, stosujesz sortowanie przez łączenie. Fragmenty, które mieszczą się w pamięci sortujesz dowolną metodą, a potem już sortujesz przez łączenie.
19 lut 20:43
Mariusz: Problem w tym że idee znam ale z napisaniem w miarę zrozumiałego pseudokodu na podstawie którego można łatwo zapisać kod źródłowy w ulubionym języku programowania to już gorzej Dla sortowania tablic taki pseudokod mają np w Algorithms unlocked
19 lut 20:54
jc: @Mariusz Pomyś, że masz dużo małych posortowanych fragmentów. Sklejasz po dwa, potem po dwa, ..., aż zostanie jeden fragment. Problemem jest sklejanie. Pomyśl, że masz dwa stosy kartek z numerami. Bierzesz kartkę z mniejszą liczbą i odkładasz na trzeci stos, itd. Ale to przecież jest opisane w dziesiątkach miejsc ...
19 lut 21:05
Mariusz: Chwalisz się że byłeś nauczycielem a nie potrafisz nawet dobrze opisać algorytmu to samo było np z rozkładem Jordana "Ale to przecież jest opisane w dziesiątkach miejsc ..." tak jedynie Wirth o tym trochę pisze ale w przeciwieństwie do Cormena trudniej napisać kod na podstawie tego co napisał U Diksa jest o tym tylko kilka zdań Większość w tym Cormen ogranicza się jednak do sortowania tablic
29 sty 10:54
g: Najprościej było by każdą wczytaną linię wstawiać od razu w dobre miejsce listy. Miejsce wstawienia najszybciej znajdziemy podziałem binarnym.
29 sty 10:59
Mariusz: Algorytm rozdzielania serii początkowych (1) Wczytaj pierwsze elementy z pliku źródłowego do tablicy, utwórz kopiec i ustaw licznik serii. Jeżeli rozmiar pliku jest niewiększy od rozmiaru kopca przejdź do kroku (3). (2) Dopóki nie wyczerpiesz pliku źródłowego, wykonuj: (2.1) Zapisz do pliku wyjściowego najmniejszy element z korzenia dolnego kopca (2.2) Odczytaj kolejny element z pliku źródłowego; jeżeli ten element należy do bieżącej serii, umieść go w korzeniu dolnego kopca i odtwórz dolny kopiec, w przeciwnym przypadku: (2.3) Jeżeli kolejny element odczytany z pliku źródłowego należy do nowej serii, wtedy umieść ostatni element kopca w korzeniu dolnego kopca, zmniejsz rozmiar dolnego kopca o 1 i umieść w korzeniu górnego kopca (poprzedni koniec dolnego kopca) odczytany element: (2.3.1) jeżeli korzeń górnego kopca znajduje się w pierwszej połowie całej tablicy, odtwórz górny kopiec; (2.3.2) jeżeli opróżnisz dolny kopiec, zwiększ liczbę serii o 1; kopiec górny wypełnia całą tablicę; (3) Dopóki tablica nie jest wyczerpana, wykonuj: (3.1) Zapisz w pliku element z korzenia dolnego kopca, przestaw element z końca kopca na początek, zmniejsz rozmiar dolnego kopca o 1 i odtwórz dolny kopiec; (3.2) Jeśli istnieje górny kopiec, przestaw ostatni element w górnym kopcu na jego korzeń (pozycja zwolniona przez ostatni element dolnego kopca) i zmniejsz o 1 indeksy górny i dolny górnego kopca − jeżeli indeks korzenia górnego kopca znajduje w pierwszej połowie całej tablicy, odtwórz górny kopiec; (4) Jeśli wyczerpano dolny kopiec, a istnieje górny kopiec, należy opróżnić go zwiększając liczbę serii o 1, jeśli chociaż raz nastąpiła zmiana serii (wykonanie kroku 2.3) . Algorytm sortowania polifazowego (1) Dopóki nie wyczerpiesz pliku źródłowego lub rozłożysz serie na n−1 plikach wyjściowych zgodnie z wymaganiami 1−go poziomu, wykonuj, co następuje: (1.1) Wyznacz na 1−ym poziomie kolejny aktywny plik wyjściowy zgodnie z planowaną liczbą serii idealnych czyli liczb Fibonacciego rzędu n−2 (1.2) Weź z pliku źródłowego po 1 serii i umieść na wyznaczonym pliku wyjściowym; (2) Dopóki nie wyczerpiesz pliku źródłowego, wykonuj, co następuje: (2.1) Wyznacz na wybranym poziomie aktywny plik wyjściowy zgodnie z planowaną liczbą serii idealnych czyli liczb Fibonacciego rzędu n−2. Jeśli osiągnięto idealną liczbę serii w tym pliku, przejdź do kroku (2.3) (2.2) Umieść na wyznaczonym pliku wyjściowym kolejną serię. Jeśli należy ona do serii umieszczonej jako ostatnia w pliku, umieść w nim następną serię i przejdź do kroku (2.1) lub zwiększ liczbę fikcyjnych serii tego pliku, jeżeli został wyczerpany plik źródłowy i przejdź do kroku (3). (2.3) Wybierz wyższy poziom rozkładania serii zgodnie z ciągiem Fibonacciego rzędu n−2, wyznacz idealną oraz fikcyjną liczbę serii dla każdego z n−1 plików wyjściowych; (3) Ustaw n − 1 plików wejściowych; (4) Dopóki nie połączysz elementów z wszystkich serii w jedną serię, czyli nie osiągniesz poziomu 0, wykonuj: (4.1) Ustaw n − ty plik wyjściowy i wyznacz najmniejszą liczbę serii na danym poziomie {idealna liczba serii w pliku n−1}; (4.2) Dopóki nie wyczerpiesz wyznaczonej idealnej liczby serii, które należy połączyć na danym poziomie, wykonuj: (4.2.1) wyznacz aktywne pliki wejściowe nie posiadające serii fikcyjnych; (4.2.2) jeśli istnieją serie fikcyjne dla wszystkich plików wejściowych, to połącz po 1 serii z każdego pliku w jedną serię fikcyjną na pliku wyjściowym, w przeciwnym przypadku wykonaj: (4.2.3) połącz po 1 serii fikcyjnej z każdego z nieaktywnych plików wejściowych, jeśli istnieją, oraz dopóki nie wyczerpiesz jednej serii rzeczywistej na każdym z aktywnych plików wejściowych, wykonuj: (4.2.2.1) weź po jednej serii o tym samym numerze z każdego aktywnego pliku wejściowego; (4.2.2.2) połącz te serie w jedną i umieść ją w pliku wyjściowym; (4.2.2.3) eliminuj pliki z wyczerpaną serią lub wyczerpane; (4.2.4) zmniejsz liczbę serii idealnych łączonych na danym poziomie; (4.3) Zamień pliki, plik wyjściowy staje się plikiem wejściowym o numerze1; (4.4) Zmniejsz poziom oraz wyznacz serie idealne oraz fikcyjne Znalazłem takie coś tylko jak na podstawie powyższego opisu algorytmu napisać kod
29 sty 11:02
Mariusz: g tutaj chodzi o możliwość sortowania także plików które nie zmieszczą się w pamięci RAM
29 sty 11:08
Dziadek Mróz: Każdy plik ma nagłówek, wczytaj nagłówek do struktury i wtedy sobie sortuj tablicę struktur
4 lut 13:40
Mariusz: Bardziej mi chodzi o realizację algorytmu z 29 stycznia 11:02 bo tak jak już wcześniej pisałem chodzi mi o możliwość sortowania plików które nie zmieszczą się w RAM
4 lut 14:03
Dziadek Mróz: Sortowanie linii w pliku tekstowym? #include <iostream> #include <fstream> #include <vector> #include <algorithm> int main(int argc, char **argv) { std::vector<std::string> vec; std::ifstream ifs; ifs.open("plik.txt"); if (ifs) { while (!ifs.eof()) { std::string linia; std::getline(ifs, linia); vec.pushback(linia); } std::sort(vec.begin(), vec.end()); for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); it++) { std::cout << *it << std::endl; } } else { perror("plik.txt"); } }
4 lut 15:48
Mariusz: To co da się wczytać do pamięci to ja sobie posortuje kopcem w przypadku tablicy albo scalaniem w przypadku nieco bardziej rozbudowanego stosu Chodzi o przypadek gdy pamięci RAM jest zbyt mało aby posortować linie w pliku
4 lut 18:30
Mariusz: Tutaj chodzi o sortowanie przez scalanie scalanie proste (nie jestem pewien czy można by było przystosować do tego iteracyjny algorytm sortowania tablic przez scalanie ) Idea jest taka że przed iteracjami mamy pojedyncze linie w pliku posortowane Po pierwszej iteracji ciągi składające się z dwóch linii są posortowane Po drugiej iteracji ciągi składające się z czterech linii są posortowane itd Wprowadzenie liczników do tego algorytmu ograniczyłoby jego możliwości w pewnym momencie moglibyśmy przekroczyć zakres typu int scalanie naturalne wykorzystuje to że już na starcie plik może zawierać ciągi posortowane zawierające więcej niż jedną linię (Gdzieś w sieci jest do tego kod źródłowy) Jest jeszcze wielokierunkowe scalanie wyważone scalanie wielofazowe którego opis dałem 29 sty 11:02
4 lut 18:51