From 560518c1f1938f05197dcac2e077d078ecf838f0 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Tue, 20 Feb 2018 08:59:05 +0100 Subject: tools.pas: tDateienMitDaten: sortierte Version automatisch verwalten --- Make.lps | 107 ++++++++++++++++++++--------------------- tools.pas | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 185 insertions(+), 82 deletions(-) diff --git a/Make.lps b/Make.lps index 0417b99..eab90cf 100644 --- a/Make.lps +++ b/Make.lps @@ -21,10 +21,10 @@ + - - - + + @@ -41,11 +41,9 @@ - - @@ -143,122 +141,121 @@ - + - + - + - - + + - - + + - + + - - + + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + - - + + - - + diff --git a/tools.pas b/tools.pas index c7b3082..13e5a88 100644 --- a/tools.pas +++ b/tools.pas @@ -5,7 +5,7 @@ unit tools; interface uses - classes, sysUtils, process, mystringlistunit, regExpr; + classes, sysUtils, process, mystringlistunit, regExpr, lowlevelunit; type tAktualitaet = (aNichtVorhanden,aVeraltet,aAktuell,aWirdErneuert); @@ -25,14 +25,22 @@ type constructor create(nam: ansiString; ak: tAktualitaet); end; tDateienMitDaten = class(tFPList) + private + sortiert: tLongintArray; istSortiert: boolean; + procedure sortiereNachNamen; inline; + procedure quickSort(li,re,ungeradheit: longint); function rItem(idx: longint): tDateiMitDatum; inline; procedure wItem(idx: longint; neu: tDateiMitDatum); inline; + function rSItem(idx: longint): tDateiMitDatum; inline; public property items[idx: longint]: tDateiMitDatum read rItem write wItem; default; + property sItems[idx: longint]: tDateiMitDatum + read rSItem; constructor create; + destructor destroy; override; procedure mrProper; function add(neu: tDateiMitDatum): longint; function gleicheNamenWie(dmd: tDateienMitDaten): boolean; @@ -41,7 +49,9 @@ type function toMyStringList: tMyStringList; function finde(name: string; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline; function finde(name: string; out istNeu: boolean; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline; - procedure sortiereNachNamen; + function findeIndex(name: string): longint; inline; + procedure matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean); + procedure delete(idx: longint); end; function min(a1,a2: tAktualitaet): tAktualitaet; inline; overload; @@ -66,7 +76,7 @@ function dateienMitGueltigerSumme(sumNam: string): tMyStringList; implementation uses - lowlevelunit, math; + math; // tDateiMitDatum ************************************************************** @@ -82,9 +92,65 @@ end; constructor tDateienMitDaten.create; begin inherited create; + setLength(sortiert,0); istSortiert:=true; end; +destructor tDateienMitDaten.destroy; +begin + setLength(sortiert,0); + inherited destroy; +end; + +procedure tDateienMitDaten.sortiereNachNamen; +var + i: longint; +begin + if istSortiert then + exit; + setLength(sortiert,count); + for i:=0 to length(sortiert)-1 do + sortiert[i]:=i; + quickSort(0,count-1,0); + istSortiert:=true; +end; + +procedure tDateienMitDaten.quickSort(li,re,ungeradheit: longint); +var + pivot: string; + l,r,tmp: longint; +begin + if li>=re then + exit; + r:=0; + for l:=li+1 to re do + if items[sortiert[l]].name<>items[sortiert[li]].name then begin + r:=1; + break; + end; + if r=0 then // nur gleiche Namen + exit; + pivot:=items[sortiert[(li+re) div 2]].name; + l:=li; + r:=re; + while l<=r do begin + while (l=0) and (vergleicheStrings(items[sortiert[r]].name,pivot)>ungeradheit-1) do + dec(r); + if l'+intToStr(r)+'+1!'); + quickSort(li,r,1-ungeradheit); + quickSort(l,re,1-ungeradheit); +end; + function tDateienMitDaten.rItem(idx: longint): tDateiMitDatum; begin result:=tDateiMitDatum(get(idx)); @@ -92,10 +158,17 @@ end; procedure tDateienMitDaten.wItem(idx: longint; neu: tDateiMitDatum); begin + assert(neu.name<>'','wItem: Dateiname darf nicht leer sein!'); put(idx,neu); istSortiert:=false; end; +function tDateienMitDaten.rSItem(idx: longint): tDateiMitDatum; inline; +begin + sortiereNachNamen; + result:=items[sortiert[idx]]; +end; + procedure tDateienMitDaten.mrProper; var i: longint; @@ -103,12 +176,14 @@ begin for i:=0 to count-1 do items[i].free; clear; + setLength(sortiert,0); + istSortiert:=true; end; function tDateienMitDaten.add(neu: tDateiMitDatum): longint; begin + assert(neu.name<>'','add: Dateiname darf nicht leer sein!'); result:=inherited add(neu); - assert(neu.name<>'','Dateiname darf nicht leer sein!'); istSortiert:=false; end; @@ -119,11 +194,9 @@ begin result:=count=dmd.count; if not result then exit; - sortiereNachNamen; - dmd.sortiereNachNamen; result:=false; for i:=0 to count-1 do - if items[i].name <> dmd[i].name then + if sItems[i].name <> dmd.sItems[i].name then exit; result:=true; end; @@ -139,15 +212,15 @@ end; procedure tDateienMitDaten.append(dmd: tDateienMitDaten); var - i,j: longint; - found: boolean; + i,j: longint; begin + j:=0; for i:=0 to dmd.count-1 do begin - found:=false; - for j:=0 to count-1 do - found:=found or (items[j].name = dmd[i].name); - if not found then - add(dmd[i]); + while (j=0) and (i'''+name+'''!'); - result:=items[li]; + assert(sItems[li].name=name,'Fehler in Bisektion: '''+sItems[li].name+'''<>'''+name+'''!'); + result:=li; exit; end; assert(li=re+1,'Fehler in Bisektion: '+intToStr(li)+'<>'+intToStr(re)+'+1!'); - insert(li,tDateiMitDatum.create); - istNeu:=true; - result:=last; - last.name:=name; - last.aktuell:=wirdAktualitaet; + result:=li; end; -procedure tDateienMitDaten.sortiereNachNamen; +procedure tDateienMitDaten.matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean); +var + re: tRegExpr; + i: longint; begin - if not istSortiert then - sort(@vergleicheNamenVonDateienMitDaten); - istSortiert:=true; + setLength(indizes,0); + if istRegex then begin + re:=tRegExpr.create; + re.expression:=regEx; + for i:=0 to count-1 do + if re.exec(items[i].name) then begin + setLength(indizes,length(indizes)+1); + indizes[length(indizes)-1]:=i; + end; + end + else begin + i:=findeIndex(regEx); + if (i>=0) and (i