Autor Wątek: Sortowanie tablicy  (Przeczytany 9964 razy)

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Sortowanie tablicy
« Odpowiedź #15 dnia: 2023.04.15, 09:52:45 »
W moim przypadku, muszę zadeklarować DIM(100,9), jednak tablica będzie zwykle wypełniona tylko częściowo.
Sortowana więc będzie tablica częściowo pusta, ale to chyba nie powinno przeszkadzać.

Zastanawiam się czy może prościej by nie było stworzyć tylko tablice, posortowanych indeksow, tej pierwszej tablicy.

Dziękuję za pomoc, pośpiechu nie ma.
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

Phonex

  • *****
  • Wiadomości: 1261
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #16 dnia: 2023.04.15, 12:27:02 »
Żeby było zabawniej ten sam algorytm ograniczony warunkiem do pierwszego znaku robi to samo 20 sekund dłużej - porównanie pierwszych znaków dwóch zmiennych wymaga dodatkowych nakładu na obcięcie tych znaków.
No czary z mleka! Nawet nie pomyślałem, że porównywanie dziesięciu elementów będzie szybsze niż jednego :o
Ciężko nawet na to wpaść.
Ten trzeci przykład, który poprzednio zamieściłem, po usunięciu drugiego indeksu, przyspieszył o 10 sekund. Wynik - 1:04


@ZbyniuR w związku z tym co powyżej, spróbowałem łączenia linii, mając nadzieję, że da się zejść poniżej minuty :)
Też stosowałem kiedyś łączenie linii, ale po to żeby skrócić program. Sądziłem że Ty też. Ale myślałem że może być jakiś zysk czasowy.
A tu niespodzianka: po połączeniu - działa dłużej! :o
Po serii szybkich testów okazało się że pętle muszą być na początku linii. FOR w głębi linii spowalnia to sortowanie o 8% (5s), NEXT w głębi linii spowalnia o 2% (1s).
Połączenie innych instrukcji rzeczywiście przyspiesza, ale niewiele o 1-2% (1s).

A jeśli chodzi o sortowania bąbelkowe:
1. Dla prawie posortowanych danych jest bombowo szybkie, po zmianie np. piątego elementu w już posortowanej tablicy uwija się w 6sek! (94% szybciej), bo można zakończyć sortowanie gdy nie ma zamian. Sortowanie wyborem przyspiesza tylko o ~10% bo zyskuje się tylko na niewykonaniu zmian p$ i min. Nawet na tym gifie porównawczym to widać.
2. Kiedyś napisałem na OPUSa sortowanie nazw w katalogu dyskietki (w asemblerze). Program okazał się mało użyteczny, bo posortowanej dyskietki nie wolno było chyba defragmentować (się chyba robiła kaszana). Ale ładnie wyglądał, bo po każdym przebiegu wyświetlałem katalog i widać było jak jeden plik elegancko "wędruje" sobie na koniec ;D Zastosowałem sortowanie  bąbelkowe, nawet nie więdząc, że tak się nazywa - po prostu wymyśliłem że tak zrobię. Nawet Bill Gilbert początkowo się zachwycał ;)


Zastanawiam się czy może prościej by nie było stworzyć tylko tablice, posortowanych indeksow, tej pierwszej tablicy.
Też myślałem, że może być odrobinę szybciej - bo nie będzie trzeba zamieniać elementów, tylko kopiować/wstawiać do drugiej tablicy. Sprawdziłem - nie, jest niestety dłużej.
Stosuje się metodę podobną do algorytmu wyboru, ale bez jego plusów, bo nie eliminuje się z tablicy pierwotnej już wybranego elementu. Więc żeby go drugi raz nie wybrać - trzeba go oznaczyć (np, wpisując literę Z). Więc już mamy tyle samo operacji co w sortowaniu, a jeszcze dochodzi to, że cały czas trzeba przeszukiwać całą tablicę, a w sortowaniu w każdym przejściu przeszukuje się o 1 element krócej.
Plus dodatkowa duża tablica też spowalnia dostęp.


Ułożyła się z tego prawdziwa "seria niefortunnych zdarzeń" ;D

smok.wawelski

  • ***
  • Wiadomości: 225
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #17 dnia: 2023.04.15, 15:29:57 »

Właściwie nie potrzebujesz sortowania tylko przepisanie jednej tablicy do drugiej na podstawie 1 litery każdego rekordu w 1 tablicy.
...
To jest odmiana sortowania z wyborem, tylko jest jedno kopiowanie a nie dwa. Myślę, że nie wyjdzie poniżej minuty...
21 sekund z optymalizacją, że jeśli znajdziemy już element, który chcemy przepisać do nowej tablicy, to na jego miejsce przepisujemy z końca tablicy inny element i skracamy pętlę o 1. Bez tej optymalizacji "sortowanie" zajmowało 41 sekund.

Oczywiście przy założeniu, że wybieramy rekordy tylko na podstawie 1 litery, jak zaznaczył TDU.

Kod:

5 DIM d$(100,10): DIM s$(100,10)
10 LET r=1
20 FOR l=65 to 99: LET k$=CHR$(l)
30 FOR n=1 to 101-r
40 IF s$(n,1)=k$ THEN LET d$(r)=s$(n): LET s$(n)=s$(100-r)
50 NEXT n
60 NEXT l

PS. Może jak nam TDU powie, do czego potrzebuje tego sortowania, to się nagle okaże, że bez sortowania się obejdzie w ogóle.

Phonex

  • *****
  • Wiadomości: 1261
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #18 dnia: 2023.04.15, 16:34:40 »
Optymalizacja robi robotę :)
Ale gdzieś jest błąd - ostatnich kilka wierszy tablicy wynikowej jest pustych. Różnie, widziałem od 2 do 6.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Sortowanie tablicy
« Odpowiedź #19 dnia: 2023.04.19, 12:38:58 »
To jakby to jednak komuś było do czegoś potrzebne, to zapraszam do załącznika :)

sort.bas to oczywiście "demo" - 100 losowych stringów po 10 znaków ładowane do tablicy. Tablica może być zadeklarowana z dowolnymi rozmiarami o ile żaden z dwóch rozmiarów nie przekracza 255. Kod może być załadowany pod - w zasadzie - dowolny adres - jest relokowalny. W linii 25 następuje przekazanie parametru - używam bufora drukarki, żeby nie kombinować. Sorter używa ROMu do znalezienia właściwego adresu i jeśli przed szukaną tablicą jest dużo innych zmiennych to dodaje to chwilę do samego kodu. W linii 50 wywoływany jest sorter - tu przez PRINT USR, bo zwraca ewentualny kod błędu: 0 - posortowane OK, 1 - nie znalazł zmiennej, 2 - liczba stringów większa niż 255, 3 - długość stringa większa niż 255.

sort.tap - tak jak poprzednio skompilowane demo bez autostartu. Załadować, zrobić RUN, poczekać na READY, klepnąć dowolny klawisz - pokażą się FRAMESy początku i końca a pomiędzy kod błędu, klepnąć dowolny klawisz i kod wyświetli posortowaną tablicę.

sort.asm to kod właściwego sortera - nadal jest brzydki ;) A do tego w związku z tym, że @tdu nie potrzebuje rozróżniania wielkości liter sortowanie jest "binarne" bez maskowania.

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Sortowanie tablicy
« Odpowiedź #20 dnia: 2023.04.19, 18:03:55 »
No to zdradze tajemnice, piszę programik START do FDD3000

Wszystko na razie w Basicu, program szczytuje, pliki do tablicy,
wyswietla je na ekranie po 15 rekordow,  mozna przesuwac kursor po jednej pozycji, ale tez po 15,
całymi stronami, w górę i w dół.
Szybkość w miarę, da się pracować, zmieściłem się w 1kB.

Planuję rozbudować program o funkcje, wchodzenia w foldery, zmiany nazw plikow,
zmiany atrybutów, kasowania plikow, itp
Ale to już powiększy plik, chciałbym się zmieścić w 4kB.

No i miło by było posortować tablicę przed jej wyświetleniem,
kod sortujący powinien być w zerowej linii pod adresem 23760.
 
Dziękuje z wykonanie kodu sortującego, pomyśle jak go zastosować.
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

Maryjan

  • *****
  • Wiadomości: 6666
  • Miejsce pobytu:
    Skarżysko-Kam.
  • Scotch whiskey and West Highland Terrier
Odp: Sortowanie tablicy
« Odpowiedź #21 dnia: 2023.04.19, 18:30:21 »
Eee... no jak program "szczytuje" to ja gratuluje :)

Ale na poważnie, ciekawy pomysł.
"Co miałem powiedzieć - przeczytałem..." Nikodem Dyzma

smok.wawelski

  • ***
  • Wiadomości: 225
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #22 dnia: 2023.04.19, 19:07:57 »
No to możesz zrobić insert w trakcie sczytywania plików - umieszczać je od razu sortując (insertując). Wtedy masz bardzo niewiele operacji za każdym razem, bo tablica jest zawsze jest posortowana. Żeby uniknąć wielokrotnego przepisywania można by mieć - tak jak sugerowałeś - dwie tablice. Jedną z danymi i drugą ze wskaźnikami określającymi pozycję danego rekordu.

PS. Czemu chciałbyś się zmieścić w 4KB?

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #23 dnia: 2023.04.19, 19:34:59 »
Pewnie chodzi o czas wczytania po starcie?

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Sortowanie tablicy
« Odpowiedź #24 dnia: 2023.04.19, 19:36:28 »
4kB bo dla dyskietek gęstych, 620kB,
mały plik zawsze zajmie tyle, w tym systemie.

Dla dyskietek normalnych, 140kB, jest to 1kB
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

steev

  • *****
  • Wiadomości: 1366
  • Miejsce pobytu:
    inode 42
Odp: Sortowanie tablicy
« Odpowiedź #25 dnia: 2023.04.19, 20:40:48 »
No to zdradze tajemnice, piszę programik START do FDD3000
Jak chcesz źródełko w asm prostego 'startu' z sortowaniem, to służę...
Demo w załączniku.
Machines should work. People should think.

trojacek

  • *****
  • Wiadomości: 6846
  • Miejsce pobytu:
    Warszawa
Odp: Sortowanie tablicy
« Odpowiedź #26 dnia: 2023.04.19, 21:20:53 »
No to możesz zrobić insert w trakcie sczytywania plików - umieszczać je od razu sortując (insertując).

To jest bardzo dobre podejście, zbliżone do implementacji tzw. listy jednokierunkowej:

https://pl.wikipedia.org/wiki/Lista

Pojedynczy element składa się ze stringa z nazwą oraz wskaźnika na kolejny element (najprościej fizyczny, 16-bitowy adres w pamięci).

Taka lista wymaga w zasadzie implementacji dwóch operacji: "chodzenia" po liście (przechodzenia do kolejnego elementu na podstawie zawartości wskaźnika) oraz wstawiania w wybrane miejsce listy (listę można w dowolnym miejscu przerwać i wsadzić tam nowy element, który scala przerwane fragmenty, tworząc spójną listę).
Czyli po pobraniu nowej nazwy, wędrujemy od początku listy i porównujemy stringi. Gdy natrafimy na string "mniejszy" (wcześniejszy alfabetycznie) od nowego, odpinamy poprzedni element listy, zmieniając mu wskaźnik na nowy element, a nowy element ma stary wskaźnik z tego poprzedniego.
Na koniec wyświetlamy wszystko, idąc od pierwszego elementu listy do jej końca (elementu z zerowym wskaźnikiem na kolejny element, lub na "wartownika", w wariancie z wartownikiem).

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Sortowanie tablicy
« Odpowiedź #27 dnia: 2023.04.27, 19:30:44 »
W końcu dopracowałem, mój program start.
Pobiera katalog dyskietki do tablicy i wyświetla w porcjach po 15 plików.
Jest to wersja maksymalnie okrojona tak aby zmieścić się w 1kB.
Nie ma żadnych ozdóbek ani wodotrysków, ma za zadanie wyświetlić pliki i po
podświetleniu uruchomić wybrany program.

Wyświetla tylko pliki basicowe.
Wczytanie podświetlonego programu Enter.
Przesuwanie podświetlenia: Q i A, oraz 1 i Z następne 15 plików.

PS. W natępnej wersji będzie sortowanie katalogu i wiele dodatkowych opcji,
ale to już raczej 4kB.



ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

tdu

  • *****
  • Wiadomości: 926
  • Miejsce pobytu:
    Gdansk
    • Nasze Wędrowanie
Odp: Sortowanie tablicy
« Odpowiedź #28 dnia: 2023.05.08, 13:41:29 »
@matofesi
Po wielu próbach doszedłem do przyczyny niedziałania kodu.
Okazuje się że zadeklarowana tablica musi być takiej samej długości
jak ilość rzeczywiście wpisanych do tablicy a$ stringów.

np. jeśli zadeklaruje DIM(100,5) to nie zadziała gdy ilość wpisów jest mniejsza niż 100.

Nie mogę z góry przewidzieć ile tych wpisów do a będzie, może być 10 a może 128,
taka jest maksymalna ilość wpisów w katalogu FDD3000.

Tak naprawdę to przemyśleniach widzę że bardziej przydatna byłaby tablica z posortowanymi indeksami do tablicy a$
proszę  :)
ZX81/ZX 48k/Zx48k+/ZX +2/ZX +2A/+3/TC2048/FDD3000/FDD5000/3"/3,5'/5,25'/Beta 48k Apina/D+/GP50s/DIVIDE CF/Masterface/Polbasic SamCoupe QL CPC6128/N100 MSX-SVI738  MSX2-VG8235

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Sortowanie tablicy
« Odpowiedź #29 dnia: 2023.05.08, 13:55:17 »
Tablica jest sortowana <b>cała</b> - jeśli nie jest wypełniona w całości to "puste" zapisy zostaną przesortowane na początek. Posortowanie zadanej liczby początkowych elementów tablicy nie powinno być problemem - trzeba by tylko pobierać parametr "z zewnątrz" a nie czytać długość tablicy.

Większym problemem jest to, że z jakiegoś powodu kod nie chce poprawnie działać jak się go umieści w REMie na początku... Owszem - sortuje, ale musi coś kaszanić w obszarze zmiennych i potem np. zmienna indeksowa nie leci po całej tablicy tylko zatrzymuje wyświetlanie po jednym ekranie. A że okazało się, że to co zrobiłem to nie to co ci było potrzebne to jakoś tak zdechło mi zacięcie do dalszych kombinacji ;)

Co do "posortowanych indeksów" zakładam, że chciałbyś mieć tablicę np. a$ zawierającą nazwy plików oraz tablicę np. a w której po "przesortowaniu" dostaniesz indeksy do kolejnych pozycji w a$ tak, żeby wyciąganie danych dawało posortowane wyniki bez faktycznego sortowania tablicy?... Wydaje mi się, że "indekser" byłby bardziej skomplikowany niż sorter... ale nie specjalnie mam koncepcję jak to zrobić, żeby się zbytnio nie narobić a do tego spełnić twoje wymagania co do prędkości oraz rozmiaru kodu.