programowanie
Filip:
Witam, mam posortowac rosnaco linie wzgledem liczy znakow wystepujacej w jeden lini i wypisac
je na ekran
Linie czytam z pliku, przyklad pliku:
abc
abcsdd
sdajdkas
skadj
sdalk
ad
Moj fragment kodu wyglada tak:
char line[1000];
char tab[1000][1000];
int k = 0;
while (fgets(line, 1000, in) != NULL) strcpy(tab[k++], line);
I to dziala, teraz chce posortowac te linie po danym kryterium − tutaj juz nie dziala poprawnie
qsort(tab, k, 2 * sizeof(char), cmp) , gdzie cmp wyglada tak:
int cmp(const void* a, const void* b) {
char* f = (char*)a;
char* s = (char*)b;
int c1 = 0, c2 = 0;
while (*f++ != '\n') c1++;
while (*s++ != '\n') c2++;
return c1 > c2;
}
Czy ktos znalazlby blad w moim kodzie? ew rozumowaniu?
30 lis 11:50
Filip: Oczywiscie jezyk programowanie C
30 lis 11:51
Filip:
Wprowadzilem kiilka modyfikacji
1) qsort
qsort(tab, k, 1000, cmp)
2) funkcja cmp
int cmp(const void* a, const void* b) {
char* f = (char*)a;
char* s = (char*)b;
return strlen(f) > strlen(s)
}
Juz dziala poprawnie
30 lis 12:21
Mariusz:
No tak a co zrobisz gdy zawartość pliku nie zmieści ci się w RAM ?
1 gru 12:23
Filip:
Czyli przykladowo, ze linia bedzie zawierac wiecej niz 1000 znakow lub ilosc lini w pliku
przekroczy 1000?
1 gru 13:29
Mariusz:
To też ale zauważ że twój pomysł na sortowanie nie zadziała gdy
np plik będzie miał większy rozmiar niż np 16 GB czy 32 GB
Jeśli chodzi o sortowanie linii w pliku to poczytaj sobie o jakimś sortowaniu zewnętrznym
np łączeniu naturalnym czy scalaniem wielofazowym
Jeśli chodzi o łączenie naturalne to mam napisany przykład zarówno w C# jak i w Javie
Jeżeli chodzi o scalanie wielofazowe to :
Ten pomysł widziałem w książce Diksa i Ryttera
2.10.1
Scalanie wielofazowe z 4 plikami
Załóżmy że bloki zostały rozłożone na pliki P0 i P1
Pliki P2 i P3 są początkowo puste
i1 = 0; i2 = 1; // numery plików wejściowych , tzn otwartych do czytania
j1 = 2; j2 = 3; // numery plików wyjściowych , tzn otwartych do pisania
while jest wiecej niz jeden blok do
(a) scal pierwszy blok na Pi1 z pierwszym blokiem na Pi2 i powstający blok
zapisz na Pj1
(b) scal następny blok na Pi1 z następnym blokiem na Pi2 i powstający blok
zapisz na Pj2
(c) powtarzaj kroki (a) i (b) (kładąc powstające bloki na przemian na pliki Pj1 i
Pj2)
aż zostanie osiągnięty koniec plików Pi1 i Pi2
(d) przewiń wszystkie pliki do początku; dodaj liczbę 2 mod 4 do i1,i2,j1,j2
odwracając w ten sposób rolę plików wejściowych
Jeżeli plik potraktujemy jako ciąg linii to
blokiem można nazwać posortowany podciąg tego ciągu
Wczytywanie do tablicy może być dobrym pomysłem do przygotowania początkowych bloków
Kiedyś na youtube widziałem kolesia który wczytywał dane z pliku do tablicy
https://www.youtube.com/watch?v=5wzmEKjNqiU
Tu masz wczytywanie danych z pliku do tablicy
Przyda się to do przygotowania początkowych bloków
1 gru 16:58
1 gru 21:12