DELPHIs Wildcard-Vergleich (5. Auflage)
Autor: Li Junyu
E-Mail: [email protected] 2003.1.5
Ich dachte, dass es in DELPHI keine fertige Funktion für Platzhalter gibt, aber dann habe ich MatchesMask() gefunden. Bevor ich diese Funktion gefunden habe, habe ich eine benutzerdefinierte Funktion erstellt, um diese Funktion zu realisieren, wenn ich mich in einem freien Zustand befand und immer noch in der Stimmung war.
Der Algorithmus des Programms ist komplizierter. Fügen Sie zuerst „?“ am Ende der Teilzeichenfolge hinzu. *‘, lesen Sie dann die Teilzeichenfolge, suchen Sie nach den Zeichen zwischen den Platzhalterzeichen in der Teilzeichenfolge, also der Teilzeichenfolge in der Teilzeichenfolge, und suchen Sie dann in der Quellzeichenfolge, um festzustellen, ob sie die Teilzeichenfolge in der Teilzeichenfolge enthält ist immer noch teuer in der Umsetzung. Viele Wendungen. Diese Funktion implementiert die folgenden Funktionen:
1. In den meisten Fällen ist es möglicherweise schneller als der rekursive Algorithmus und MatchesMask().
2. Korrekter Vergleich von Sternchen und Fragezeichen in allen Fällen implementiert; //Dies kann noch einige Zeit dauern, um überprüft zu werden
3. Chinesisch unterstützen; // Sternchen und Fragezeichen müssen in Englisch sein, um gültig zu sein
4. Unterstützt die Auswahl unter Berücksichtigung der Groß- und Kleinschreibung.
Beachten Sie, dass es einen Unterschied zwischen dem Hinzufügen von Sternchen am Anfang und am Ende der Teilzeichenfolge gibt. Dieser Algorithmus ähnelt möglicherweise der Funktion, die mit dem rekursiven Algorithmus auf dem Stapel implementiert wird, hat jedoch einige Verbesserungen an der Rekursion vorgenommen. In den meisten Fällen ist es schwierig, schneller zu sein ? Sicherlich. Zumindest gibt es diese Schätzung: Wenn der Wildcard-Vergleich nur zum Suchen von Teilzeichenfolgen verwendet wird, z. B. die Quellzeichenfolge „1111111111“ und die Teilzeichenfolge „*11111112*“, beträgt die Zeitkomplexität der Verwendung des rekursiven Algorithmus O(N*M ), aber ich habe geschrieben Diese Funktion wird dann auf die Zeitkomplexität eines mehrmaligen Aufrufs der POS()-Funktion vereinfacht. Vielleicht kann man sich POS() in DELPHI als den „Knut-Morris-Pratt (KMP)-Algorithmus“ O(N+M) vorstellen . Der Geschwindigkeitsvergleich mit dem rekursiven Algorithmus ist für eine geringe Anzahl von Malen nicht offensichtlich. Wenn die Quellzeichenfolge 100 aufeinanderfolgende Einsen und die Teilzeichenfolge 99 aufeinanderfolgende Einsen aufweist und schließlich das Zeichen 2 hinzugefügt wird, ist dies nach dem Testen in einer 1000-maligen Schleife mehrere Sekunden schneller als der rekursive Algorithmus und 20 Sekunden schneller als MatchesMask() Funktion. Sekunden. Meine tatsächlichen Mehrfachtests zeigen, dass alle drei manchmal die schnellsten sind, aber MatchesMask() scheint die meiste Zeit langsamer zu sein, und die Geschwindigkeit der Rekursion variiert stark. Die von mir geschriebene Funktion ist möglicherweise durchschnittlich schnell. Es ist nur so, dass die von mir geschriebenen Funktionen nur als Referenz dienen. Ich übernehme keine Verantwortung für etwaige Probleme.
function isABClikeAX(const abc,ax:widestring):boolean; file://abc ist die Quellzeichenfolge und ax ist die Teilzeichenfolge
var
abcstart,axstart,abclength,axlength:integer;
endpartabc,endpartax,subax:widestring;
temp,abcwww,axwww:integer;
begin file://aaa
temp:=0;
abcstart:=1;
axstart:=1;
axwww:=1;
abcwww:=1;
abclength:=length(abc);
Achsenlänge:=Länge(Achse);
isabclikeax:=true;
while axstart<=axlength do//Wenn die Länge der Quellzeichenfolge größer oder gleich der Teilzeichenfolge ist
begin//bbb
wenn abcstart> abclength dann
beginnen
if (ax[axlength]='*') and (axlength=axstart) then isabclikeax:=true
else isabclikeax:=false;//Wenn die Teilzeichenfolge länger als die Quellzeichenfolge ist
brechen;
Ende;
wenn ax[axstart]='?'
beginnen
inc(axstart);
inc(abcstart);
weitermachen;
Ende;
wenn ax[axstart]='*' dann
beginnen
inc(axstart);
temp:=1;
axwww:=axstart;
abcwww:=abcstart;
weitermachen;
Ende;
wenn nicht((ax[axstart]='?') oder (ax[axstart]='*') ) dann
begin//ccc
endpartax:=copy(ax,axstart,axlength-axstart+1)+'?*';
subax:=copy(endpartax,1,min(pos('?',endpartax),pos('*',endpartax))-1);
axstart:=axstart+min(pos('?',endpartax),pos('*',endpartax))-1;
endpartabc:=copy(abc,abcstart,abclength-abcstart+1);
if ((pos(subax,endpartabc)<>0) and (temp=1 )) or ((pos(subax,endpartabc)=1) and (temp=0)) then
begin//ddd
wenn temp=1 dann temp:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+length(subax)-1) ;
Ende//TT
sonst//ddd
begin//ddd
wenn (temp=0) und (axwww>1) dann
beginnen
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
temp:=1;
weitermachen;
Ende;
isabclikeax:=false;
brechen;
end;//ddd
Ende;//ccc
Ende;//bbb
if (result) and (abcstart<=abclength) and (ax[axlength]<>'*') then isabclikeax:=false;//Wenn die Quellzeichenfolge länger als die Teilzeichenfolge ist
Ende;//aaa
FUNCTION IsLike(abc,ax:string):boolean; file://case-sensitive-Funktion
beginnen
islike:=isABClikeAX(abc,ax);
Ende;
FUNKTION WideCard(abc,ax:string):boolean; file://case-insensitive-Funktion
beginnen
abc:=uppercase(abc);
ax:=uppercase(ax);
widecard:=isABClikeAX(abc,ax);
Ende;
Achten Sie auf USES MATH, da MIN() verwendet wird. Sie können MIN() auch durch eine IF-Anweisung ersetzen, dies ist jedoch nicht klar genug.
Vielen Dank an einige Internetnutzer, die mir einige korrekte Einblicke gegeben haben, die mir geholfen haben, die Überarbeitung in die richtige Richtung zu lenken.