PDA

Ver la Versión Completa : Salir de un procedimiento recursivo


cardomjar
16-04-2005, 21:24:01
Hola: defino el siguiente procedimiento recursivo:

procedure Tform1.brute(n:integer; str:string);
var
ord:integer;
begin
if (n > 0)then
begin
for ord := 65 to 90 do
begin
brute(n-1, str+chr(ord));
end
end
else
begin
// Llama a una rutina asmCode que bajo determinadas circunstancias hace que final
se ponga a true
asmCode(str);
if(final = true) then
begin
// Aquí es donde quiero salirme del todo
exit;
end
end;
end;

Este procedimiento (de forma más o menos afortunada) genera todas cadenas posible compuestas por letras mayúsculas de "n" caracteres. Es llamado desde pongamos por caso, el procedimiento X.
Llegado el momento quiero que cuando se den determindas circunstancias (cuando final sea true) no siga calculando combinaciones, es decir, deseo salirme del todo, no sólo del procedimiento actual, sino que vuelva al procedimiento X. Con exit (el ejemplo que muestro), no funciona ya que se sale del procedimiento brute, pero continúa calculando combinaciones.
Espero haberme explicado.

Gracias de antemano y un saludo.

marcoszorrilla
16-04-2005, 21:59:50
procedure Tform1.brute(n:integer; str:string);
var
ord:integer;
begin
if (n > 0)then
begin
for ord := 65 to 90 do
begin
brute(n-1, str+chr(ord));
end;
end
else
begin
// Llama a una rutina asmCode que bajo determinadas circunstancias
hace que final se ponga a true
asmCode(str);
if(final = true) then
begin
// Aquí es donde quiero salirme del todo
exit;
end
end;
end;

Acabo de hacer unas pruebas y sale sin ningún problema lo que ocurre es que dependiendo el número que le
pongamos tarda más o menos.
En mi caso hasta el número 4 va relativamente rápido de ahí hacia arriba da la sensación de colgarse pero al
final sale.

Un Saludo.

roman
17-04-2005, 00:02:08
Para poder volver al procedimiento x se necesita salir de todos los niveles de recursividad a los que se haya entrado.

Cuando llamas a exit el flujo de la aplicación salta sólo al procedimiento más inmediato que haya llamado, que normalmente no será x, sino el mismo brute dentro del ciclo for y por tanto continúa a la siguiente iteración (en el nivel recursivo anterior) así que tendrías que volver a examinar el valor de final luego de la llamada a brute en el ciclo;


for ord := 65 to 90 do
begin
brute(n-1, str+chr(ord));
if final then exit;
end;


Esto no hace que llegues directamente al procedimiento x sino que genera una llamada a exit "en cascada" que se va transmitiendo hacia arriba en cada nivel de recursividad.

Haz un trazado del código paso a paso y te quedará más claro lo que está sucediendo.

// Saludos

cardomjar
18-04-2005, 20:07:38
Marcos, muchas gracias por tu respuesta; no debí explicarme con claridad, ya que, en efecto, el procedimiento funciona correctamente. Lo que quería era que cuando encontrase una combinación correcta (final = true) no siguiese calculando. Yo lo lanzo para 7 caracteres, que vienen a ser algo más de ocho mil millones de combinaciones. Si encuentra la combinación que ando buscando, pongamos por caso cuando lleva dos mil millones, no quiero que realice los seis mil millones de cálculos restantes.

Probé sin embargo la solución propuesta por Román (gracias), y funcionó a las mil maravillas. En cuanto la encuentra se sale y además inmediatamente. Yo pensaba que al hacer los exit en cascada tardaría bastante en salir, pero que va, inmediatamente para afuera.

De nuevo gracias a los dos y un saludo.