PDA

Ver la Versión Completa : Búsqueda de texto en TMemo


ixMike
09-10-2006, 19:24:51
Hola a todos,
veréis, estoy desarrollando un componente, derivado de TMemo, que cuenta con algún método extra. Entre estos métodos, hay uno de búsqueda, el cual es muy completo (CaseSensitive, TildeSensitive...). Me funciona a la perfección, pero lo que ocurre es que es muy lento, y el programa en el que lo uso se queda bloqueado unos segundos antes de encontrar la palabra "FIN" en el archivo "COPYING" traducción al español.

¿Alguna sugerencia para agilizarlo? Este es el código (un poco largo, lo sé):


const
MinusA = ['a', 'á', 'ä', 'à', 'ê', 'å'];
MinusE = ['e', 'é', 'ë', 'è', 'ê'];
MinusI = ['i', 'í', 'ï', 'ì', 'î'];
MinusO = ['o', 'ó', 'ö', 'ò', 'ô'];
MinusU = ['u', 'ú', 'ü', 'ù', 'û'];

MayusA = ['A', 'Á', 'Ä', 'À', 'Â', 'Å'];
MayusE = ['E', 'É', 'Ë', 'È', 'Ê'];
MayusI = ['I', 'Í', 'Ï', 'Ì', 'Î'];
MayusO = ['O', 'Ó', 'Ö', 'Ò', 'Ô'];
MayusU = ['U', 'Ú', 'Ü', 'Ù', 'Û'];

MinusN = ['n', 'ñ'];
MayusN = ['N', 'Ñ'];
MinusY = ['y', 'ý', 'ÿ'];
MayusY = ['Y', 'Ý'];

Todo = [#0..#255];
Minus = ['a'..'z', 'ñ'] + MinusA + MinusE + MinusI + MinusO + MinusU + MinusY;
Mayus = ['A'..'Z', 'Ñ'] + MayusA + MayusE + MayusI + MayusO + MayusU + MayusY;
Letras = Minus + Mayus;
Puntuacion = Todo - Letras;


type

TSearchTextRec = record
Text: string;
CaseSensitive,
TildeSensitive,
IgnorePunctuation,
WholeWords: Boolean;
end;

TNewMemo=class(TMemo)
{...}

Function SonIguales(c1, c2: Char; CaseSensitive, TildeSensitive, IgnorePunctuation: Boolean): Boolean;
begin
Result:=False;
If not CaseSensitive then
begin
c1:=AnsiLowerCase(c1)[1];
c2:=AnsiLowerCase(c2)[1];
end;
If c1=c2 then
begin
Result:=True;
exit;
end;
dIf IgnorePunctuation then
if ((c1 in Puntuacion)and(c2 in Puntuacion))then
begin
Result:=True;
Exit;
end;
If not TildeSensitive then
begin
if(((c1 in MinusA)and(c2 in MinusA))or
((c1 in MinusE)and(c2 in MinusE))or
((c1 in MinusI)and(c2 in MinusI))or
((c1 in MinusO)and(c2 in MinusO))or
((c1 in MinusU)and(c2 in MinusU))or
((c1 in MinusN)and(c2 in MinusN))or
((c1 in MinusY)and(c2 in MinusY))or
((c1 in MayusA)and(c2 in MayusA))or
((c1 in MayusE)and(c2 in MayusE))or
((c1 in MayusI)and(c2 in MayusI))or
((c1 in MayusO)and(c2 in MayusO))or
((c1 in MayusU)and(c2 in MayusU))or
((c1 in MayusN)and(c2 in MayusN)))then Result:=True;
end;
end;


Function TNewMemo.SearchFirst(R: TSearchTextRec): Integer;
var
n, i: Integer;
Encontrado: Boolean;
begin
Result:=0;
If Length(Text)=0 then Exit;
If Length(R.Text)=0 then Exit;
If Length(R.Text)>Length(Text)then Exit;
Encontrado:=False;
n:=0;
repeat
Inc(n);
If SonIguales(Text[n],R.Text[1],R.CaseSensitive,R.TildeSensitive,R.IgnorePunctuation)then Encontrado:=True;
If not Encontrado then Continue;
i:=0;
repeat
Inc(i);
If not SonIguales(Text[n+i-1],R.Text[i],R.CaseSensitive,R.TildeSensitive,R.IgnorePunctuation)then Encontrado:=False;
until Encontrado=False or (i=Length(R.Text));
If not Encontrado then Continue;
If R.WholeWords then
begin
If n>1 then
if not(Text[n-1] in Puntuacion)then Encontrado:=False;
If (n+Length(R.Text)-1)<Length(Text)then
if not(Text[n+Length(R.Text)] in Puntuacion)then Encontrado:=False;
end;
until Encontrado or(n=Length(Text)-Length(R.Text)+1);
If Encontrado then Result:=n;
end;


El caso es que si pruebo este código en un programa de prueba (sin usar el nuevo componente) es bastante más rápido.

Muchísimas gracias por vuestro tiempo e interés.


EDITO: Se me acaba de ocurrir sustituir esto


if(((c1 in MinusA)and(c2 in MinusA))or
((c1 in MinusE)and(c2 in MinusE))or
((c1 in MinusI)and(c2 in MinusI))or
((c1 in MinusO)and(c2 in MinusO))or
((c1 in MinusU)and(c2 in MinusU))or
((c1 in MinusN)and(c2 in MinusN))or
((c1 in MinusY)and(c2 in MinusY))or
((c1 in MayusA)and(c2 in MayusA))or
((c1 in MayusE)and(c2 in MayusE))or
((c1 in MayusI)and(c2 in MayusI))or
((c1 in MayusO)and(c2 in MayusO))or
((c1 in MayusU)and(c2 in MayusU))or
((c1 in MayusN)and(c2 in MayusN)))then Result:=True;


por esto otro


If c1 in MayusA then c1:='A';
If c1 in MayusE then c1:='E';
...
If c1 in MinusA then c1:='a';
If c1 in MinusE then c1:='e';
...
If c2 in MayusA then c2:='A';
If c2 in MayusE then c2:='E';
...
If c2 in MinusA then c2:='a';
If c2 in MinusE then c2:='e';
...
If c1=c2 then Result:=True;


¿Este cambio tendrá algún efecto?