Comparação de curingas do DELPHI (5ª edição)
Autor: Li Junyu
e-mail: [email protected] 2003.1.5
Achei que não existia uma função pronta para curingas no DELPHI, mas então encontrei MatchesMask(). Antes de encontrar essa função, eu costumava criar uma função personalizada para realizá-la quando estava livre e ainda com vontade.
O algoritmo do programa é mais complicado. Primeiro adicione '?' *', leia a substring, procure os caracteres entre os caracteres curinga na substring, ou seja, a substring na substring e, em seguida, pesquise na string de origem para ver se ela contém a substring na substring. ainda é caro para implementar. Muitas reviravoltas. Esta função implementa as seguintes funções:
1. Pode ser mais rápido que o algoritmo recursivo e MatchesMask() na maioria dos casos;
2. Implementada comparação correta de asteriscos e pontos de interrogação em todos os casos //Isso ainda pode precisar de tempo para ser verificado;
3. Suporte Chinês; //Asteriscos e pontos de interrogação devem estar em inglês para serem válidos
4. Suporta seleção com distinção entre maiúsculas e minúsculas.
Observe que há uma diferença entre adicionar asteriscos no início e no final da substring. Este algoritmo pode ser semelhante à função implementada usando o algoritmo recursivo na pilha, mas na verdade é um pouco diferente. Ele fez algumas melhorias na recursão. Pode ser mais rápido que o processo recursivo na maioria dos casos. ? Certamente. Pelo menos existe esta estimativa: quando a comparação de curingas é usada apenas para encontrar substrings, como a string de origem é "1111111111" e a substring é "*11111112*", a complexidade de tempo do uso do algoritmo recursivo é O(N*M ), mas eu escrevi Esta função será então simplificada para a complexidade de tempo de chamar aproximadamente a função POS() várias vezes. Talvez POS() em DELPHI possa ser imaginado como o "algoritmo Knut-Morris-Pratt (KMP)" O(N+M) abaixo. . A comparação da velocidade com o algoritmo recursivo não é óbvia por um pequeno número de vezes. Quando a string de origem tem 100 1's consecutivos e a substring tem 99 1's consecutivos e finalmente o caracter 2 é adicionado, após testar em um loop de 1000 tempos, é vários segundos mais rápido que o algoritmo recursivo e 20 segundos mais rápido que MatchesMask() função segundos. Meus vários testes reais mostram que todos os três às vezes são os mais rápidos, mas MatchesMask() parece ser mais lento na maioria das vezes e a velocidade da recursão varia muito. Acontece que as funções que escrevi são apenas para referência. Não serei responsável por quaisquer problemas caso ocorram.
function isABClikeAX(const abc,ax:widestring):boolean file://abc é a string de origem e ax é a substring
var
abcstart,axstart,abclength,axlength:inteiro;
endpartabc,endpartax,subax:string larga;
temp,abcwww,axwww:inteiro;
arquivo inicial: //aaa
temperatura:=0;
abcstart:=1;
axstart:=1;
axwww:=1;
abcwww:=1;
abccomprimento:=comprimento(abc);
comprimento do eixo:=comprimento(ax);
isabclikeax:=verdadeiro;
while axstart<=axlength do//Quando o comprimento da string de origem é maior ou igual à substring
começar //bbb
se abcstart> abclength então
começar
if (ax[axlength]='*') e (axlength=axstart) então isabclikeax:=true
else isabclikeax:=false;//Quando a substring é maior que a string de origem
quebrar;
fim;
se ax[axstart]='?'
começar
inc(axstart);
inc(abcstart);
continuar;
fim;
se ax[axstart]='*' então
começar
inc(axstart);
temperatura:=1;
axwww:=axstart;
abcwww:=abcstart;
continuar;
fim;
se não((ax[axstart]='?') ou (ax[axstart]='*') ) então
começar // 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);
se ((pos(subax,endpartabc)<>0) e (temp=1 )) ou ((pos(subax,endpartabc)=1) e (temp=0)) então
começar //ddd
se temp=1 então temp:=0;
abcstart:=abcstart+(pos(subax,endpartabc)+length(subax)-1) ;
fim //ddd
senão //ddd
começar //ddd
se (temp=0) e (axwww>1) então
começar
axstart:=axwww;
abcwww:=abcwww+1;
abcstart:=abcwww;
temperatura:=1;
continuar;
fim;
isabclikeax:=falso;
quebrar;
fim; //ddd
fim; //ccc
fim; //bbb
if (resultado) and (abcstart<=abclength) and (ax[axlength]<>'*') then isabclikeax:=false;//Quando a string de origem é maior que a substring
fim; //aaa
FUNCTION IsLike(abc,ax:string):boolean; file://função que diferencia maiúsculas de minúsculas
começar
é como:=éABCcomoAX(abc,ax);
fim;
FUNÇÃO WideCard(abc,ax:string):boolean; file://função sem distinção entre maiúsculas e minúsculas
começar
abc:=maiúsculas(abc);
machado:=maiúsculas(ax);
cartão largo:=isABClikeAX(abc,ax);
fim;
Preste atenção em USES MATH, porque MIN() é usado, você também pode usar uma instrução IF para substituir MIN(), mas não é claro o suficiente.
Obrigado a alguns internautas por me fornecerem alguns insights corretos, o que me ajudou a fazer a revisão na direção certa.