Comparación de comodines de DELPHI (quinta edición)
Autor: Li Junyu
correo electrónico: [email protected] 2003.1.5
Pensé que no había una función lista para usar para comodines en DELPHI, pero luego encontré MatchesMask(). Antes de encontrar esta función, solía crear una función personalizada para realizar esta función cuando estaba en un estado libre y todavía de humor.
El algoritmo del programa es más complicado. Primero agregue '?' * ', luego lea la subcadena, busque los caracteres entre los caracteres comodín en la subcadena, es decir, la subcadena en la subcadena, y luego busque en la cadena de origen para ver si contiene la subcadena en la subcadena. Su implementación sigue siendo costosa. Esta función implementa las siguientes funciones:
1. Puede ser más rápido que el algoritmo recursivo y MatchesMask() en la mayoría de los casos;
2. Se implementó la comparación correcta de asteriscos y signos de interrogación en todos los casos. //Es posible que aún necesite tiempo para verificarse;
3. Soporte chino; //Los asteriscos y los signos de interrogación deben estar en inglés para ser válidos.
4. Admite selección que distingue entre mayúsculas y minúsculas.
Tenga en cuenta que existe una diferencia entre agregar asteriscos al principio y al final de la subcadena. Este algoritmo puede ser similar a la función implementada usando el algoritmo recursivo en la pila, pero en realidad es algo diferente. Ha realizado algunas mejoras en la recursividad. Puede que sea mucho más rápido que el proceso recursivo. ¿Difícil? Ciertamente. Al menos existe esta estimación: cuando la comparación con comodines solo se usa para encontrar subcadenas, como la cadena de origen es "1111111111" y la subcadena es "*11111112*", la complejidad temporal del uso del algoritmo recursivo es O (N*M ), pero escribí Luego, esta función se simplificará a la complejidad temporal de llamar aproximadamente a la función POS() varias veces. Quizás POS() en DELPHI pueda imaginarse como el "algoritmo Knut-Morris-Pratt (KMP)" O(N+M) a continuación. . La comparación de velocidad con el algoritmo recursivo no resulta obvia durante un breve período de tiempo. Cuando la cadena de origen tiene 100 unos consecutivos, la subcadena tiene 99 unos consecutivos y finalmente se agrega el carácter 2. Después de probar en un bucle de 1000 veces, es varios segundos más rápido que el algoritmo recursivo y veinte segundos más rápido que MatchesMask(). función segundos. Mis múltiples pruebas reales muestran que los tres son a veces los más rápidos, pero MatchesMask() parece ser más lento la mayor parte del tiempo y la velocidad de recursividad varía mucho. La función que escribí puede tener una velocidad promedio. Es solo que las funciones que escribí son solo de referencia. No seré responsable de ningún problema si ocurre.
la función esABClikeAX(const abc,ax:widestring):boolean file://abc es la cadena fuente y ax es la subcadena
var
abcstart,axstart,abclength,axlength:entero;
endpartabc,endpartax,subax:widestring;
temp,abcwww,axwww:entero;
comenzar archivo://aaa
temperatura:=0;
inicioabc:=1;
inicioax:=1;
hachawww:=1;
abcwww:=1;
abclongitud:=longitud(abc);
longitud del eje:=longitud(ax);
isabclikeax:=verdadero;
while axstart<=axlength do//Cuando la longitud de la cadena de origen es mayor o igual que la subcadena
comenzar//bbb
si abcstart> abclength entonces
comenzar
si (ax[axlength]='*') y (axlength=axstart) entonces isabclikeax:=true
else isabclikeax:=false;//Cuando la subcadena es más larga que la cadena fuente
romper;
fin;
si ax[axstart]='?' entonces
comenzar
inc(inicioax);
inc(abcinicio);
continuar;
fin;
si ax[axstart]='*' entonces
comenzar
inc(inicioax);
temperatura:=1;
hachawww:=axstart;
abcwww:=abcstart;
continuar;
fin;
si no ((ax[axstart]='?') o (ax[axstart]='*') ) entonces
comenzar//ccc
endpartax:=copiar(ax,axstart,axlength-axstart+1)+'?*';
subax:=copiar(endpartax,1,min(pos('?',endpartax),pos('*',endpartax))-1);
axstart:=axstart+min(pos('?',endpartax),pos('*',endpartax))-1;
endpartabc:=copiar(abc,abcstart,abclength-abcstart+1);
si ((pos(subax,endpartabc)<>0) y (temp=1 )) o ((pos(subax,endpartabc)=1) y (temp=0)) entonces
comenzar//ddd
si temp=1 entonces temp:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+longitud(subax)-1);
fin//ddd
más//ddd
comenzar//ddd
si (temp=0) y (axwww>1) entonces
comenzar
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
temperatura:=1;
continuar;
fin;
isabclikeax:=falso;
romper;
fin;//ddd
fin;//ccc
fin;//bbb
if (resultado) y (abcstart<=abclength) y (ax[axlength]<>'*') entonces isabclikeax:=false;//Cuando la cadena de origen es más larga que la subcadena
fin;//aaa
FUNCIÓN IsLike(abc,ax:string):boolean; archivo://función que distingue entre mayúsculas y minúsculas
comenzar
escomo:=esABCcomoAX(abc,ax);
fin;
FUNCIÓN WideCard(abc,ax:string):boolean; archivo://función que no distingue entre mayúsculas y minúsculas
comenzar
abc:=mayúscula(abc);
hacha:=mayúscula(hacha);
tarjeta ancha:=isABClikeAX(abc,ax);
fin;
Preste atención a USES MATH, debido a que se usa MIN (), también puede usar una declaración IF para reemplazar MIN (), pero no es lo suficientemente claro.
Gracias a algunos internautas por darme algunas ideas correctas, que me ayudaron a realizar la revisión en la dirección correcta.