1 REM Ins{nd av Kristoffer Eriksson <5357> 1986-06-17 01.38.11
100 ! --------------------------------------------------------
110 ! WILDCARD.BAS - N}gra Wildcardfunktioner j{mf|rda
120 ! F|r ABC800-BASIC, 1986-06-16
130 ! Skrivet och m{tt av Kristoffer Eriksson <5357>
140 ! Kan n}gon komma p} en snabbare rutin i BASIC?
150 ! --------------------------------------------------------
160 !
170 ! H{r finns 5 olika testdata att m{ta tiden med. Den wildcardfunktion som
180 ! ska m{tas f}r skrivas in f|r hand i m{tloopen nedan. Alla m{tningar
190 ! gjorda med 20 varv i loopen.
200 !
210 ! Test 1: Inga wildcards
220 ! Test 2: En stj{rna
230 ! Test 3: Fyra stj{rnor
240 ! Test 4: Fyra stj{rnor, fler "blindg}ngar" i B$
250 ! Test 5: En stj{rna, mer normal str{ngl{ngd
260 INPUT "Testnr=";T
270 IF T=1 A$="ABCDEFGHIalsbcdkugbllkuflui" : B$="ABCDEFEFGHIalsbcdkugbllkuflui"
280 IF T=2 A$="ABCDEFGHI*bcdefghij" : B$="ABCDEFGHIalsbcdkugllkufluibcdefghij"
290 IF T=3 A$="ABCD*EFGHI*bc*d*j" : B$="ABCDEFGHIalsbcdkugllkufluibcdefghij"
300 IF T=4 A$="ABCD*EFGHI*bc*d*j" : B$="ABCDEFEFGHIalsbcdkugbllkufluibcdjefghij"
310 IF T=5 THEN A$="ABC*DE" : B$="ABCEDE"
320 !
330 WHILE PEEK(-11)>0 : WEND
340 ; TIME$ PEEK(-11)
350 FOR I=1 TO 20
360 Z=FNWildil(A$,B$)
370 NEXT I
380 ; TIME$ PEEK(-11)
390 END
400 ! FNWild.. (sek) 1 2 3 4 5
410 ! ---------------------------------------------------------
420 ! . Str{ngloop 0.74 6.52 8.33 9.76 0.74
430 ! p Pekloop GOTO 0.55 7.35 8.91 10.42 0.89
440 ! r Helrekursiv 0.54 5.26 5.92 6.00 0.73
450 ! - Helrek INSTR 0.55 2.17(!)1.72 2.48
460 ! ri Helrek INSTRloop 0.55 2.06 1.72 2.25 0.61
470 ! i INSTR 0.13 0.51 1.04 1.38 0.33
480 ! il INSTRloop 0.14 0.56 1.15 1.53 0.37
490 !
500 ! ASC(X$)=N {r snabbare {n X$='N' eller LEFT$(X$,1)='N'
510 ! RIGHT$(,) och LEFT$(,) {r snabbare {n MID$(,,)
520 ! ASC(RIGHT$(X$,))=N {r snabbare {n MID$(X$,,1)='N'
530 ! LEN(X$)=0 {r snabbare {n X$=''
540 ! A$=B$ {r f|rst}s effektivare ju l{ngre str{ngarna {r
550 ! INSTR(,,,) {r f|rst}s snabbare {n en BASIC-s|kloop
560 !
570 !
580 ! --- Str{ngtilldelning i j{mf|relseloop
590 !
600 DEF FNWild(Wc$,St$) LOCAL W$=80,S$=80 ! W$=20,S$=20
610 IF LEN(St$)=0 IF LEN(Wc$)=0 OR Wc$='*' THEN RETURN -1 ELSE RETURN 0
620 IF LEN(Wc$)=0 THEN RETURN 0
630 W$=Wc$ : S$=St$
640 WHILE ASCII(W$)=63 OR ASCII(W$)=ASCII(S$)
650 W$=RIGHT$(W$,2) : S$=RIGHT$(S$,2)
660 IF W$=S$ THEN RETURN -1
670 IF LEN(W$)<>0 AND LEN(S$) WEND
680 IF ASCII(W$)<>42 THEN RETURN 0
690 IF LEN(W$)=1 RETURN -1 ! Lika
700 IF FNWild(RIGHT$(W$,2),S$) RETURN -1
710 IF FNWild(W$,RIGHT$(S$,2)) RETURN -1
720 RETURN 0
730 FNEND
740 !
750 !
760 ! --- Pekare i str{ng, j{mf|relseloop med GOTO
770 !
780 DEF FNWildp(Wc$,St$) LOCAL P
790 P=P+1
800 IF P>LEN(St$) IF P>LEN(Wc$) RETURN -1 ELSE 840
810 IF P>LEN(Wc$) THEN RETURN 0
820 IF ASCII(RIGHT$(Wc$,P))=ASCII(RIGHT$(St$,P)) THEN 790
830 IF ASCII(RIGHT$(Wc$,P))=63 THEN 790
840 IF ASCII(RIGHT$(Wc$,P))<>42 THEN RETURN 0
850 IF P=LEN(Wc$) THEN RETURN -1 ! Lika
860 IF FNWildp(RIGHT$(Wc$,P+1),RIGHT$(St$,P)) RETURN -1
870 IF FNWildp(RIGHT$(Wc$,P),RIGHT$(St$,P+1)) RETURN -1
880 RETURN 0
890 FNEND
900 !
910 !
920 ! --- Helt rekursiv metod. Slukar minne j{mf|rt med de |vriga, men inte
930 ! s} mycket man skulle kunna tro, eftersom str{ngar |verf|rs med pekare.
940 !
950 DEF FNWildr(Wc$,St$)
960 IF LEN(St$)=0 IF LEN(Wc$)=0 OR Wc$='*' THEN RETURN -1 ELSE RETURN 0
970 IF LEN(Wc$)=0 THEN RETURN 0
980 IF ASCII(Wc$)=ASCII(St$) RETURN FNWildr(RIGHT$(Wc$,2),RIGHT$(St$,2))
990 IF ASCII(Wc$)=63 THEN RETURN FNWildr(RIGHT$(Wc$,2),RIGHT$(St$,2))
1000 IF ASCII(Wc$)<>42 THEN RETURN 0
1010 IF FNWildr(RIGHT$(Wc$,2),St$) RETURN -1
1020 IF FNWildr(Wc$,RIGHT$(St$,2)) RETURN -1
1030 RETURN 0
1040 FNEND
1050 !
1060 !
1070 ! --- Rekursiv, men anv{nder INSTR f|r att s|ka efter tecknet efter '*'.
1080 ! Detta spara massor av tid, eftersom INSTR ers{tter an massa BASIC med
1090 ! maskinkod. H{r anv{nds en loop om INSTR inte hittar r{tt vid f|rsta
1100 ! f|rs|ket, men det g}r ungef{r lika snabbt (n}got andra karakt{ristika)
1110 ! att l}ta rutinen anropa sig sj{lv i det l{get, men det drar mer minne.
1120 !
1130 DEF FNWildri(Wc$,St$) LOCAL P
1140 IF LEN(St$)=0 IF LEN(Wc$)=0 OR Wc$='*' THEN RETURN -1 ELSE RETURN 0
1150 IF LEN(Wc$)=0 THEN RETURN 0
1160 IF ASCII(Wc$)=ASCII(St$) RETURN FNWildri(RIGHT$(Wc$,2),RIGHT$(St$,2))
1170 IF ASCII(Wc$)=63 THEN RETURN FNWildri(RIGHT$(Wc$,2),RIGHT$(St$,2))
1180 IF ASCII(Wc$)<>42 THEN RETURN 0
1190 IF LEN(Wc$)=1 THEN RETURN -1
1200 P=INSTR(P+1,St$,MID$(Wc$,2,1)) : IF P=0 THEN RETURN 0
1210 IF FNWildri(RIGHT$(Wc$,2),RIGHT$(St$,P)) RETURN -1
1220 GOTO 1200
1230 ! IF FNWildri(Wc$,RIGHT$(St$,P+1)) RETURN -1 ELSE RETURN 0
1240 FNEND
1250 !
1260 !
1270 ! --- Helt INSTR-baserad. Wildcards s|ks upp med INSTR, och delarna
1280 ! d{remellan behandlas som hela str{ngar. Detta |verf|r {nnu mera av
1290 ! jobbet till maskinkod, {ven om rutinen blivit ganska gr|tig. N}got
1300 ! av den rekursiva karakt{ren {r dock kvar.
1310 !
1320 DEF FNWildi(Wc$,St$) LOCAL P,P2
1330 IF LEN(St$)=0 IF LEN(Wc$)=0 OR Wc$='*' THEN RETURN -1 ELSE RETURN 0
1340 P=INSTR(1,Wc$,"?")
1350 P2=INSTR(1,Wc$,"*")
1360 IF P+P2=0 THEN RETURN Wc$=St$
1370 IF P IF P