Unterprogrammbibliothek Exsort – Sortieren mit Komfort
Exsort zeichnet sich zum einen durch die Sortiergeschwindigkeit aus. Zum anderen werden sowohl numerische als auch alphanumerische Felder auf- oder absteigend sortiert. Ein weiterer Clou: Ein zweites Feld kann abhängig vom ersten Feld mitsortiert werden.
Jeder Programmierer ärgert sich irgendwann einmal über das langsame Basic, das vor allem beim Suchen und Sortieren stört. Gute Sortierroutinen, in Assembler geschrieben, kann nicht jeder entwickeln. Viele Sort-Programme sind aber auch sehr einseitig: Entweder sortieren sie nur aufsteigend oder lediglich alphanumerische Felder. Exsort kann beides und noch mehr.
Vorteile:
- Zirka zehnmal so schnell wie die schnellste Basic-Version.
- Die Befehle können in jedem Basic-Programm angewendet werden.
- Unterprogramme in Basic, die oft nur ein bestimmtes Feld in einer Richtung sortieren können, entfallen.
- Die Erweiterung belegt keinen Basic-Speicher.
- Beim Sortieren von Strings kommt es nicht zu einem zeitraubenden Garbage-Collect, da die Descriptoren vertauscht werden.
- Ein zweites Feld, das Informationen über das erste Feld enthält, kann mitsortiert werden.
- Das zu sortierende Feld kann numerisch oder alphanumerisch sein.
Nachteile:
- Es kann nicht mit Exbasic oder Simons Basic zusammen genutzt werden.
- Es kann nicht compiliert werden.
1. Befehl »so«
Syntax: so, (feldname), (anfangsindex), (endindex), (sortierungsrichtung)
Dieser Befehl sortiert ein beliebiges eindimensionales Feld innerhalb von zwei Grenzen mit einer vom Benutzer gewählten Sortierungsrichtung.
Beispiel 1:
Das Feld heißt ax$, alphanumerisch aufsteigend sortieren (von Index 100 bis Index 5000).
Befehl: so,ax$,100,5000,1 (1 = aufsteigend)
Beispiel 2:
Das Feld heißt qe%, numerisch absteigend sortieren (von Index 0 bis zu dem Index, der in der Variable »en« enthalten ist).
Befehl: so,qe%,0,en,0 (0 = absteigend)
Option: Manchmal ist es notwendig, daß Daten, die in einem zweiten Feld vorhanden sind, entsprechend dem ersten Feld sortiert werden.
Syntax: so,(feldname 1), (anfangsindex), (endindex), (sortierungsrichtung), (feldname2)
Beispiel: Das Feld fe$ soll alphanumerisch aufsteigend von Index 0 bis Index 10 sortiert werden. Die Daten in dem Realfeld »nr« sollen entsprechend dem ersten Feld sortiert werden.
Befehl: so,fe$,0,10,1,nr
2. Befehl: »se«
Syntax: se,(feldname),(anfangsindex),(endindex),(element)
Dieser Befehl durchsucht ein beliebiges eindimensionales Feld innerhalb von zwei Grenzen nach einem Element.
Beispiel: Es soll die Zahl - 12 in dem Feld rt% von Index 0 bis Index 100 gesucht werden.
Befehl: se,rt%,0,100, - 12
Wenn das Element gefunden wird, enthält die Variable »in« den jeweiligen Index. Wird das Element nicht gefunden, so enthält »in« den Wert -1.
Fehlermeldungen:
- type mismatch:
Sie versuchten, einen String in einem numerischen Feld zu suchen (oder umgekehrt). - wrong index:
Beim Suchen war der Anfangsindex größer als der Endindex. - bad subscript:
Index außerhalb des zulässigen Bereiches. - only one dimension array:
Sie können nur eindimensionale Felder durchsuchen oder sortieren. - array not found:
Das Feld war nicht durch einen DIM-Befehl dimensioniert worden. - wrong array name:
Geben Sie bitte nur die ersten beiden Buchstaben des Feldnamen ein (plus % oder $ wenn nötig). Es wird dann sicher funktionieren. - wrong sorting direction error:
Sie haben einen anderen Wert als 0 oder 1 als Sortierungsrichtung angegeben.
Zu den Programmen:
Listing 1
Das Programm »Exsort data« erstellt das Maschinenprogramm aus DATA-Zeilen und speichert es als »Exsort«-Absolutprogramm auf Diskette oder Kassette. Sie können es dann jederzeit durch LOAD »Exsort«, 8,1 absolutladen. Dabei geht ein Basic-Programm nicht verloren (siehe auch Listing 2, Demo-Programm).
Listing 2
Das Programm »Exsort demo« lädt das Absolutprogramm »Exsort« nach und startet es. Danach folgt eine Demonstration der beiden Befehle.
Um »Exsort« zu laden, muß Zeile 0 des Basic-Programms lauten:
0 if k = 0 then k = 1 : load"ex-sort",8,1 (für Diskette)
0 if k = 0 then k = 1 : load"ex-sort",1,1 (für Kassette)
In Zeile 1 muß stehen:
1 sys 49400
Da die Erweiterung nur einmal geladen und gestartet werden muß, kann sie bei späteren Starts des Programms übersprungen werden.
(Marcus Rickert/gk)0 rem ********************************* 1 rem **maschinencode sortierroutine ** 2 rem ** ** 3 rem ** von marcus rickert ** 4 rem ********************************* 100 data169,3,141,8,3,169,193,141,9,3,96,160,1,177,122,1395 110 data201,83,240,3,76,228,167,200,177,122,201,69,208,3,76,2054 120 data218,197,201,79,208,239,32,115,0,32,115,0,32,115,0,1583 130 data32,253,174,32,236,196,32,36,195,76,88,193,32,253,174,2002 140 data32,138,173,32,247,183,165,20,141,0,192,165,21,141,1,1651 150 data192,32,253,174,32,138,173,32,247,183,165,20,141,2,192,1976 160 data165,21,141,3,192,96,32,49,193,32,253,174,32,158,183,1724 170 data142,4,192,224,2,144,7,162,120,160,197,76,250,196,32,1908 180 data199,195,142,6,192,140,7,192,141,8,192,160,0,177,122,1873 190 data240,4,201,58,208,8,169,0,141,11,192,76,162,193,32,1695 200 data253,174,32,236,196,32,36,195,32,199,195,142,9,192,140,2063 210 data10,192,141,11,192,169,0,141,5,192,160,0,32,60,197,1502 220 data160,2,32,60,197,169,0,141,246,192,141,247,192,160,18,1957 230 data32,80,197,144,3,76,174,167,160,16,32,80,197,162,16,1536 240 data160,18,32,42,197,142,20,192,140,21,192,162,20,160,246,1744 250 data32,154,196,240,219,48,217,173,16,192,141,12,192,173,17,2022 260 data192,141,13,192,173,18,192,141,14,192,173,19,192,141,15,1808 270 data192,32,239,195,160,6,174,8,192,232,138,162,12,32,1,1775 280 data197,32,47,196,240,23,72,173,4,192,208,6,104,16,14,1524 290 data76,27,194,104,48,8,162,12,32,227,196,76,251,193,160,1766 300 data6,174,8,192,232,138,162,14,32,1,197,32,47,196,240,1671 310 data23,72,173,4,192,208,6,104,48,14,76,67,194,104,16,1301 320 data8,162,14,32,209,196,76,35,194,162,12,160,14,32,154,1460 330 data196,240,2,16,103,160,6,174,8,192,232,138,162,12,32,1673 340 data1,197,134,251,132,252,160,6,174,8,192,232,138,162,14,2053 350 data32,1,197,134,253,132,254,172,8,192,32,105,197,173,11,1893 360 data192,240,38,160,9,174,11,192,232,138,162,12,32,1,197,1790 370 data134,251,132,252,160,9,174,11,192,232,138,162,14,32,1,1894 380 data197,134,253,132,254,172,11,192,32,105,197,162,12,32,227,2112 390 data196,162,14,32,209,196,162,14,160,12,32,154,196,48,3,1590 400 data76,251,193,162,14,160,16,32,42,197,142,20,192,140,21,1658 410 data192,162,18,160,12,32,42,197,142,22,192,140,23,192,162,1688 420 data20,160,22,32,154,196,16,34,162,12,160,18,32,154,196,1368 430 data16,10,160,12,32,60,197,160,18,32,60,197,173,14,192,1333 440 data141,18,192,173,15,192,141,19,192,76,200,193,162,16,160,1890 450 data14,32,154,196,16,10,160,16,32,60,197,160,14,32,60,1153 460 data197,173,12,192,141,16,192,173,13,192,141,17,192,76,200,1927 470 data193,169,4,141,20,192,162,0,134,3,134,4,32,115,0,1303 480 data240,63,201,58,240,59,201,36,240,20,201,37,240,24,201,2061 490 data44,240,47,21,3,149,3,224,2,240,32,232,76,47,195,1555 500 data169,2,141,20,192,76,99,195,169,1,141,20,192,165,3,1585 510 data9,128,133,3,165,4,9,128,133,4,76,47,195,162,158,1354 520 data160,197,76,250,196,165,47,133,251,165,48,133,252,76,164,2313 530 data195,160,0,177,251,197,3,208,10,200,177,251,197,4,208,2238 540 data3,76,183,195,160,2,24,165,251,113,251,170,8,200,40,1841 550 data165,252,113,251,133,252,138,133,251,165,251,197,49,208,212,2770 560 data165,252,197,50,208,206,162,143,160,197,76,250,196,160,4,2426 570 data177,251,201,1,208,1,96,162,185,160,197,76,250,196,24,2185 580 data160,6,177,251,237,2,192,8,136,177,251,40,237,3,192,2069 590 data176,7,162,0,169,18,76,59,164,24,165,251,105,7,170,1553 600 data165,252,105,0,168,173,20,192,96,24,173,16,192,109,18,1703 610 data192,170,173,17,192,109,19,192,74,141,21,192,138,106,141,1877 620 data20,192,174,8,192,232,138,160,6,162,20,32,1,197,134,1668 630 data40,132,41,173,8,192,201,4,208,4,138,76,162,187,174,1740 640 data8,192,138,168,177,40,149,97,202,136,16,248,96,134,40,1841 650 data132,41,173,8,192,201,2,240,9,201,1,240,65,138,32,1675 660 data91,188,96,160,1,177,40,133,3,200,177,40,133,4,160,1603 670 data0,76,98,196,177,3,209,98,240,8,176,3,169,1,96,1550 680 data169,255,96,200,152,160,0,209,40,240,8,197,97,240,4,2067 690 data168,76,83,196,177,40,197,97,240,5,176,229,76,91,196,2047 700 data169,0,96,165,97,141,21,192,165,98,141,20,192,160,0,1657 710 data177,40,141,23,192,200,177,40,141,22,192,162,20,160,22,1709 720 data189,0,192,217,0,192,208,11,189,1,192,217,1,192,208,2009 730 data3,76,124,196,189,1,192,48,23,185,1,192,48,164,56,1498 740 data189,0,192,249,0,192,189,1,192,249,1,192,144,152,76,2018 750 data91,196,185,1,192,16,144,76,183,196,56,189,0,192,233,1950 760 data1,157,0,192,189,1,192,233,0,157,1,192,96,254,0,1665 770 data192,208,3,254,1,192,96,165,122,56,233,1,133,122,165,1943 780 data123,233,0,133,123,96,134,34,132,35,76,71,164,133,40,1527 790 data189,0,192,133,113,189,1,192,133,114,169,0,133,41,152,1751 800 data72,32,87,179,134,40,132,41,104,168,24,165,40,121,0,1339 810 data192,170,165,41,121,1,192,168,96,56,185,0,192,253,0,1832 820 data192,72,185,1,192,253,1,192,168,104,170,96,174,5,192,1997 830 data185,0,192,157,25,192,185,1,192,157,136,192,232,142,5,1993 840 data192,96,174,5,192,202,16,2,56,96,189,25,192,153,0,1590 850 data192,189,136,192,153,1,192,142,5,192,24,96,177,251,170,2112 860 data177,253,145,251,138,145,253,136,16,243,96,255,87,82,79,2356 870 data78,71,32,83,79,82,84,73,78,71,32,68,73,82,69,1055 880 data67,84,73,79,206,65,82,82,65,89,32,78,79,84,32,1197 890 data70,79,85,78,196,87,82,79,78,71,32,65,82,82,65,1231 900 data89,32,78,65,77,197,87,82,79,78,71,32,73,78,68,1186 910 data69,216,79,78,76,89,32,79,78,69,32,68,73,77,69,1184 920 data78,83,73,79,78,32,65,82,82,65,217,0,255,0,255,1444 930 data0,255,32,255,0,32,115,0,32,115,0,32,115,0,32,1015 940 data253,174,32,236,196,32,36,195,32,49,193,32,199,195,142,1996 950 data6,192,140,7,192,141,8,192,32,253,174,32,158,173,162,1862 960 data2,160,0,32,154,196,16,7,162,174,160,197,76,250,196,1782 970 data173,8,192,201,2,240,20,32,141,173,173,8,192,201,4,1760 980 data240,23,32,170,177,133,97,132,98,76,57,198,32,163,182,1810 990 data133,97,165,34,133,98,165,35,133,99,174,8,192,232,138,1836 1000 data160,6,162,0,32,1,197,142,9,192,140,10,192,174,9,1426 1010 data192,172,10,192,32,47,196,240,42,162,0,160,2,32,154,1633 1020 data196,240,26,162,0,32,227,196,56,173,9,192,109,8,192,1818 1030 data141,9,192,173,10,192,105,0,141,10,192,76,75,198,169,1683 1040 data255,160,255,76,134,198,173,1,192,172,0,192,32,145,179,2164 1050 data169,0,133,13,133,14,169,73,133,69,169,78,133,70,32,1388 1060 data231,176,166,71,164,72,32,212,187,76,174,167,255,0,255,2238 1100 zn=100:z=49400:restore:rem ** einlesen der werte ** 1110 pr=0 1120 fors=0to14:readx:pr=pr+x:pokez+s,x:nexts 1130 readx:ifx=prthen1150 1140 printchr$(14)"{rvon}Pruefsummen-Fehler in Zeile";zn:end 1150 zn=zn+10:z=z+15 1160 ifz<>50855then1110 1170 print"fertig" 1180 input"{down}cassette(1) oder diskette(8)";pn 1190 poke251,pn:rem ** abspeichern als absolutprogramm ** 1200 poke252,peek(45):poke253,peek(46) 1210 poke43,248:poke44,192 1220 poke45,172:poke46,198 1230 ifpeek(251)=1thensave"exsort",1,2 1240 ifpeek(251)<>1thensave"@:exsort",peek(251) 1250 poke43,1:poke44,8:poke45,peek(252):poke46,peek(253)
0 ifk=0thenk=1:load"exsort?",8,1:rem laden von exsort 1 sys49400:rem starten von exsort 100 rem *********************** 110 rem *** exsort demo *** 120 rem *********************** 130 rem 140 rem ****************** 150 rem * 1.befehl: "so" * 160 rem ****************** 165 print"{clr}Erster Befehl: 'so'" 170 input"{down}Zahl der zu sortierenden Elemente";a 175 print"{down}Anfuellen des Feldes 'za' mit Zufalls- zahlen" 180 dimza(a) 190 rem *** das feld za wird mit zufallszahlen belegt *** 200 fors=1toa 210 :za(s)=rnd(1)*10000-5000 220 nexts 230 it=ti:rem zeit speichern 240 print"{down}Sortierbeginn" 250 rem 260 rem *** aufruf des befehls "so" *** 270 so,za,1,a,1 280 rem so = befehl 290 rem za = feldname 300 rem 1 = anfangsindex 310 rem a = endindex 320 rem 1 = sortierungsrichtung(aufsteigend) 330 rem 340 it=ti-it 350 print"{down}Sortierende" 355 fors=1to1000:nexts 360 rem *** ausgabe der sortierten elemente *** 370 fors=1toa 380 :prints,tab(6)za(s) 390 nexts 400 print"{down}Zeit:"it/60"sec" 410 print"{down}bitte Taste druecken" 420 gett$:ift$=""then420 430 rem 440 rem ****************** 450 rem * 2.befehl: "se" * 460 rem ****************** 470 rem 480 clr:dimfe$(10000) 485 print"{clr}Zweiter Befehl 'se'" 490 rem ** in 50 beliebige elemente ** 500 rem ** des feldes fe$ wird das ** 510 rem ** wort "hallo" geschrieben ** 520 rem 525 print"{down}In 50 beliebige Elemente von fe$ wird 'hallo' geschrieben" 530 fors=1to50 540 :fe$(rnd(1)*10000)="hallo" 550 nexts 560 print"{down}In folgendem elementen steht 'hallo':" 570 rem 580 rem ** ausdrucken jedes indexes ** 590 rem ** in dem "hallo" steht ** 600 rem 610 in=-1:it=ti 620 rem ** aufruf des befehls "se" ** 630 se,fe$,in+1,10000,"hallo" 640 rem se = befehl 650 rem fe$ = feldname 660 rem in+1 = anfangsindex 670 rem 10000 = endindex 680 rem "hallo" = element 690 rem ** bei rueckkehr aus "se" ** 700 rem ** enthaelt "in" den index ** 710 rem ** oder (wenn das element ** 720 rem ** nicht gefunden wurde) ** 730 rem ** den wert -1 ** 740 ifin=-1orin=10000then760 750 printin,:goto630 760 print:print"{down}Zeit:"(ti-it)/60"sec" 770 print"{down}bitte Taste druecken" 780 gett$:ift$=""then780 790 rem 800 rem **************************** 810 rem * 1.befehl 'so' mit option * 820 rem **************************** 830 rem 835 print"{clr}Erster Befehl mit option" 840 datanull,zwei,vier,sechs,acht,zehn,eins,drei,fuenf,sieben,neun 850 data0,2,4,6,8,10,1,3,5,7,9 860 clr:dimnr(10),nr$(10) 870 rem ** einlesen in feld nr$ ** 880 fors=0to10 890 :readx$:nr$(s)=x$ 900 nexts 910 rem ** einlesen in feld nr ** 920 fors=0to10 930 :readx:nr(s)=x 940 nexts 950 rem ** ausgabe feld vor sortierung ** 960 print"{down}Index nr$ vorher nr * nr$ nachher nr" 970 fors=0to10 980 :prints;tab(6)nr$(s)tab(16)nr(s) 990 nexts 1000 rem ** aufruf des befehl "so" mit option ** 1010 so,nr$,0,10,0,nr 1020 rem so = befehl 1030 rem nr$ = feldname 1 1040 rem 0 = anfangsindex 1050 rem 10 = endindex 1060 rem 0 = sortierungsrichutng(absteigend) 1070 rem nr = feldname 2 1080 rem 1090 print"{down}Sortieren von nr$ absteigend" 1095 print"{down}nr wird entsprechend mitsortiert" 1097 print"{down}bitte Taste druecken" 1098 gett$:ift$=""then1098 1100 rem ** ausgabe feld nach sortierung ** 1110 print"{home}{down}{down}{down}"; 1120 fors=0to10 1130 :printtab(22)nr$(s)tab(33)nr(s) 1140 nexts 1150 print"{down}{down}{down}{down}{down}{down}"