Documentos de Académico
Documentos de Profesional
Documentos de Cultura
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 19. Recursión.
19. RECURSION
19.1. Conceptos.
Una cadena de llamados recursivos debe terminar en algún momento; por esta razón los
subprogramas recursivos deben colocar dentro de una instrucción condicionada el llamado
recursivo.
a) Número natural:
i) 1 es un número natural.
ii) el sucesor de un número natural es un número natural.
d) Números de Fibonacci:
i) fib(0) = 1; fib(1) = 1
ii) fib(n) = fib(n-1)+fib(n-2) para n>1
a) function fact(i:integer):integer;
begin
if i>0
then fact:=i*fact(i-1)
else fact:=1
end;
b) function mcd(m,n:integer):integer;
begin
if n=0
then mcd:=m
else mcd:=mcd(n,m mod n)
end;
c) function fib(n:integer):integer;
begin
if n=0
then fib:=0
else if n=1
then fib:=1
else fib:=fib(n-1)+fib(n-2)
end;
Algunos de estos ejemplos han sido desarrollados antes por algoritmos repetitivos.
Nótese que los llamados recursivos están dentro de estructuras de control condicional.
19.3. Ejemplos.
19.3.1. Permutaciones.
begin
for i:=1 to 3 do
for j:=1 to 3 do
for k:=1 to 3 do
if (i<>j) and (i<>k) and (j<>k)
then writeln(i,j,k);
end.
a) Se mantiene a[n] en su lugar; y se generan todas las permutaciones de los n-1 objetos
restantes. Es decir se invoca a permute(n-1).
b) Se repite a) previo cambio de a[n] con a[1].
c) Se sigue repitiendo a) efectuando el cambio a[n] con a[i] para i=2 hasta n-1.
procedure permute(k:integer);
var i : integer;
begin
if k=1
then salida
else
begin {se mantiene a[k] en su lugar}
program permutaciones(input,output);
procedure salida;
var i : integer;
begin
for i:=1 to n do write(a[i]);
writeln
end;
procedure permute(k:integer);
procedure con_el_i_en_k;
procedure cambio_k_por_i;
var t : char;
begin
t:=a[i]; a[i]:=a[k]; a[k]:=t;
end;
var i : integer;
begin {con el i en k}
for i:=1 to k-1 do
begin
cambio_k_por_i; permute(k-1); cambio_k_por_i
end
end;
begin {permute}
if k=1
then salida
else
begin
permute(k-1); {cona[k]fijo,genera las
permutaciones de los k-
1 objetos Permutaciones
precedentes.}
con_el_i_en_k {repite con a[i] en
Entrada
el lugar de
a[k], para i desde 1 a k-
1. } Salida
end
end;
Permute
begin {principal}
con_el_i_en_k
Cambio
Prof. Leopoldo Silva Bijit. 07-07-2003 247
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 19. Recursión.
entrada;
permute(n)
end.
SALIDA debe estar antes de PERMUTE, para ser accesible desde este último. CAMBIO
es accesible sólo desde con_el_i_en_k.
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
.....
Emplearemos la notación:
n
C (n ,k ) =
k
Se tienen:
C(n,0) = 1 n >=0
C(n,k) = 0 n<k
C(n,k) = C(n-1,k)+C(n-1,k-1) 0<=k<=n
function C(n,k:integer):integer;
begin
if k=0
then C:=1
else
if n<k
then C:=0
else C:=C(n-1,k)+C(n-1,k-1)
end;
Pero también:
C(n,k) = n! / k!(n-k)!
function C(n,k:integer):integer;
var num,den : integer;
begin
num:=1; den:=1;
for j:=1 to k do
begin
num:=num*(n+1-j);
den:=den*j
end;
C:=num div den
end;
program combinaciones(kbd,output);
procedure salida;
var i : integer;
begin writeln; for i:=1 to n do write(b[a[i]]) end;
procedure combine;
var p,b : integer;
begin
salida; {escribe la inicial}
p:=1;
while p<=n do
begin
writeln('Generacion de combinaciones');
entrada;
combine
end.
Se desea saber si una determinada secuencia de caracteres cumple las reglas sintácticas
siguientes :
t1 + t2 --> t1t2+
t1 - t2 --> t1t2-
f1 * f2 --> f1f2*
f1 / f2 --> f1f2/
(e) --> e
[e] --> e
Se aprovecha el programa que permite recorrer la sintaxis para generar código; en este
caso, se produce una secuencia en notación polaca inversa que podría posteriormente ser
evaluada en una pila.
Se emplea la técnica de leer un carácter por adelantado; y al mismo tiempo se valida que el
carácter recién leído pertenezca al conjunto válido de caracteres siguientes.
Nótese que el texto del programa refleja las producciones. La generación de la secuencia
polaca inversa se logra, no pasando los paréntesis hacia el arreglo de salida; y posponiendo el
paso de los operadores, hasta haber encontrado el siguiente factor o término.
program polaca;
const largo=20;
var ch : char;
salida : array[1..largo] of char;
cursor : integer;
cpar : integer;
procedure leach;
begin
read(kbd,ch) {no estándar}
end;
procedure error;
begin write(chr(07)); leach(ch) end;
procedure wrtpol;
var i : integer;
begin
for i:=1 to largo+10-cursor-cpar do write(' ');
procedure expresion;
var sumop : char;
procedure termino;
var mulop : char;
procedure factor;
begin {factor}
if ch='('
then
begin
write(ch);
leach(ch); while not (ch in ['a'..'z','(','[']) do error;
expresion;
while ch <> ')' do error; cpar:=cpar+2
end
else
if ch='['
then
begin
write(ch);
leach(ch);whilenot(ch in['a'..'z','(','['])do error;
expresion;
while ch <> ']' do error; cpar:=cpar+2
end
else
begin
while (ch<'a') or (ch>'z') do error;
wrt(ch)
end;
write(ch);
leach(ch);
whilenot (ch in ['*','/','-','+',')',']','.']) do error;
end; {factor}
begin {termino}
factor;
while (ch='*') or (ch='/') do
begin
write(ch); mulop:=ch;
leach(ch); while not (ch in ['a'..'z','(','[']) do error;
factor; wrt(mulop)
end
end; {termino}
begin {expresion}
termino;
while (ch='+') or (ch='-') do
begin
write(ch); sumop:=ch;
leach(ch); while not (ch in ['a'..'z','(','[']) do error;
termino; wrt(sumop)
end
end; {expresion}
begin {polaca}
clrsrc; {no estándar}
writeln('Entre <expresion>"." Y la paso a polaca inversa.');
write('- >');
leach(ch); while not (ch in ['a'..'z','(','[','.']) do error;
while ch <> '.' do
begin
cursor:=0; cpar:=0;
expresion;
wrtpol; writeln;
write('->');
leach(ch);whilenot(ch in['a'..'z','(','[','.']) do error;
end
end.