Comparaison Wildcard de DELPHI (5e édition)
Auteur : Li Junyu
courriel : [email protected] 2003.1.5
Je pensais qu'il n'y avait pas de fonction prête à l'emploi pour les caractères génériques dans DELPHI, mais j'ai ensuite trouvé MatchesMask(). Avant de trouver cette fonction, j'avais l'habitude de créer une fonction personnalisée pour réaliser cette fonction lorsque j'étais libre et toujours d'humeur.
L'algorithme du programme est plus compliqué. Ajoutez d'abord '?' à la fin de la sous-chaîne. *', puis lisez la sous-chaîne, recherchez les caractères entre les caractères génériques dans la sous-chaîne, c'est-à-dire la sous-chaîne dans la sous-chaîne, puis recherchez dans la chaîne source pour voir si elle contient la sous-chaîne dans la sous-chaîne. est encore coûteux à mettre en œuvre. Beaucoup de rebondissements. Cette fonction implémente les fonctions suivantes :
1. Il peut être plus rapide que l'algorithme récursif et MatchesMask() dans la plupart des cas ;
2. Implémentation d'une comparaison correcte des astérisques et des points d'interrogation dans tous les cas // Cela peut encore prendre du temps pour être vérifié ;
3. Prise en charge du chinois ; //Les astérisques et les points d'interrogation doivent être en anglais pour être valides.
4. Prend en charge la sélection sensible à la casse.
Notez qu'il existe une différence entre l'ajout d'astérisques au début et à la fin de la sous-chaîne. Cet algorithme peut être similaire à la fonction implémentée à l'aide de l'algorithme récursif sur la pile, mais il est en fait quelque peu différent. Il a apporté quelques améliorations à la récursivité. Il peut être plus rapide que le processus récursif dans la plupart des cas. ? Certainement. Il existe au moins cette estimation : lorsque la comparaison avec des caractères génériques est uniquement utilisée pour rechercher des sous-chaînes, par exemple, la chaîne source est "1111111111" et la sous-chaîne est "*11111112*", la complexité temporelle de l'utilisation de l'algorithme récursif est O(N*M ), mais j'ai écrit Cette fonction sera ensuite simplifiée à la complexité temporelle d'appeler approximativement la fonction POS() plusieurs fois. Peut-être que POS() dans DELPHI peut être imaginé comme « l'algorithme de Knut-Morris-Pratt (KMP) » O(N+M) ci-dessous. . La comparaison de vitesse avec l’algorithme récursif n’est pas évidente dans un petit nombre de fois. Lorsque la chaîne source a 100 1 consécutifs et que la sous-chaîne a 99 1 consécutifs et que finalement le caractère 2 est ajouté, après un test dans une boucle de 1 000 fois, il est plusieurs secondes plus rapide que l'algorithme récursif et 20 secondes plus rapide que MatchesMask(). fonction secondes. Mes multiples tests montrent que les trois sont parfois les plus rapides, mais MatchesMask() semble être plus lent la plupart du temps et la vitesse de récursion varie considérablement. La fonction que j'ai écrite peut être moyenne en vitesse. C'est juste que les fonctions que j'ai écrites sont uniquement à titre de référence, je ne serai pas responsable des problèmes s'ils surviennent.
function isABClikeAX(const abc,ax:widestring):boolean; file://abc est la chaîne source et ax est la sous-chaîne
var
abcstart,axstart,abclength,axlength:entier ;
endpartabc,endpartax,subax:widestring;
temp,abcwww,axwww:entier;
commencer le fichier://aaa
température :=0 ;
abcstart:=1;
axstart:=1;
axwww:=1;
abcwww:=1;
abclength:=longueur(abc);
longueuraxe:=longueur(hache);
isabclikeax:=true;
while axstart<=axlength do//Lorsque la longueur de la chaîne source est supérieure ou égale à la sous-chaîne
début // bbb
si abcstart> abclength alors
commencer
si (ax[axlength]='*') et (axlength=axstart) alors isabclikeax:=true
else isabclikeax:=false;//Lorsque la sous-chaîne est plus longue que la chaîne source
casser;
fin;
si ax[axstart]='?' alors
commencer
inc(débutax);
inc(abcstart);
continuer;
fin;
si ax[axstart]='*' alors
commencer
inc(débutax);
température :=1 ;
axwww:=axstart;
abcwww:=abcstart;
continuer;
fin;
sinon ((ax[axstart]='?') ou (ax[axstart]='*') ) alors
début // 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);
si ((pos(subax,endpartabc)<>0) et (temp=1 )) ou ((pos(subax,endpartabc)=1) et (temp=0)) alors
début//jdd
si temp=1 alors temp:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+length(subax)-1) ;
fin //jj
sinon//ddd
début//jdd
si (temp=0) et (axwww>1) alors
commencer
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
température :=1 ;
continuer;
fin;
isabclikeax:=false;
casser;
fin;//jdd
fin;//ccc
fin;//bbb
if (result) et (abcstart<=abclength) et (ax[axlength]<>'*') then isabclikeax:=false;//Lorsque la chaîne source est plus longue que la sous-chaîne
fin;//aaa
FUNCTION IsLike(abc,ax:string):boolean; fichier://fonction sensible à la casse
commencer
islike:=isABClikeAX(abc,ax);
fin;
FONCTION WideCard(abc,ax:string):boolean; fichier://fonction insensible à la casse
commencer
abc:=majuscule(abc);
hache:=majuscule(hache);
Widecard:=isABClikeAX(abc,ax);
fin;
Faites attention à USES MATH, car MIN() est utilisé, vous pouvez également utiliser une instruction IF pour remplacer MIN(), mais ce n'est pas assez clair.
Merci à certains internautes de m'avoir donné des informations correctes, ce qui m'a aidé à faire la révision dans le bon sens.