Está en la página 1de 15

ROSMEL RONALDO CHILA VILCA ………………………………………….

180180

ESTRUCTURA Y RECURSIVIDAD
OBJETIVOS
1. Aplicar y utilizar las estructuras de tipo registro o struct en los programas del usuario
2. Conocer y aplicar la recursividad de sus programas.

PARTE I: ESTRUCTURAS

Una estructura (denominada también agregados o colección de variables) permite gestionar un


objeto compuesto. A diferencia de los array que poseen elementos de un mismo tipo de dato
las estructuras poseen elementos heterogéneos, como una sola unidad

El concepto de struct o registro(record) es fundamental para el diseño, concepción y


construcción de un archivo(s) de base de datos.

La figura 5.1. Presenta algunos ejemplos clásicos de estructuras: (a) la estructura fecha, (b)
tiempo, (c) punto y (d) complejo.

(a) (b) (c) (c)


fecha tiempo punto punto

día hora x x

mes min y y
g
year seg

Figura 5.1: Abstracción de las estructuras fecha, tiempo, punto y complejo

En seguida se presenta sus correspondientes declaraciones


(a) (b) (c) (d)

struct fecha{ struct tiempo{ struct complejo


struct punto{
int dia; short hora; {
int x;
int mes; short min; float real;
int y;
int year; short seg; float imag;
}p1, p2
}; hoy ; }; };

Otro ejemplo es la estructura alumno con datos miembros: código, nombre curso, y un array de
notas
struct alumno{
char codigo[10]; //cadena
char nombre[40]; //cadena
char curso[20]; //cadena
int notas[4]; //array de enteros
};unmsm, pucp, uni;

Una estructura puede estar anidada es decir uno o más de sus datos miembro pueden ser a su
vez uns struct. Por ejemplo si ya tuene declarada la struct fecha, se puede declarar la struct
persona del siguiente modo

struct persona{
char nombre[30];
char direccion[40];
struct fecha nac; //una struct dentro de otra
short edad;
};

Note que aquí; el dato miembro nac es una struct del tipo fecha. Este dato miembro también
puede declararse sin enunciar la palabra reservada struct, siempre y cuando, como ya se dijo
haya sido declarada previamente.

OPERADORES DE ACCESO A LOS CAMPOS O MIENBROS DE UNA STRUCT


Los lenguaje C y C++ proporcionan dos operadores para el acceso a los miembros de una struct

1)El operador de acceso a miembro, llamado también operador punto.

Ejemplo:

#include <iostream>
/*Ilustrarel uso del operador punto*/
struct fecha{
int dia,mes,year;
};
using namespace std;

int main() //Estructura_1.cpp


{
struct fecha hoy;
cout<<"Ingrese fecha de hoy (dd/mm/aaaa); ";
cin>> hoy.dia>>hoy.mes>>hoy.year;
cout<<"\n El dia de hoy es; ";
cout<<hoy.dia<<'\'<<hoy.mes<<'\'<<hoy.year<<endl;

return 0;
}

2) Operador de flecha o también operador puntero a miembro. ->


Ejemplo:
#include <iostream>
/*Ilustrarel uso del operador punto*/
struct fecha{
int dia,mes,year;
}hoy;
using namespace std;

int main() //Estructura_2.cpp


{
struct fecha *aptr; //declaracion del apuntador
aptr = &hoy; //inicializacion del apuntador
cout<<"\nIngrese fecha de hoy: ";
cin>> aptr->dia >> aptr->mes >> aptr->year;
cout<<"\n El dia de hoy es; ";
cout<<aptr->dia<<'/'<<aptr->mes<<'/'<<aptr->year<<endl;

return 0;

Ejemplo

1.
#include <iostream>
using namespace std;

struct complejo{
float real; // componente real
float imag; //componente imaginaria
};
//funcion prototipo, retorna un complejo
completo suma(completox, completo y);
completo resta(completox, completo y);

int main() //Estructura_2.cpp


{
completo x,y,z;

cout << "\nIngrese parte real y parte imaginaria de x -> ";


cin >> x.real >> x.imag;
cout << "\nIngrese parte real y parte imaginaria de y -> ";
cin >> y.real >> y.imag;
z = suma(x,y);
cout<< "\n;La suma es ; "<< z.real << " + "
<< z.imag <<"i"<<end;
z = resta(x,y);
cout<< "\n;La resta es ; "<< z.real << " + "
<< z.imag <<"i"<<end;

return 0;
}

complejo suma(complejo x, complejo y)//calcula la suma de dos complejos


{
complejo z;
z.reak = x.real + y.real; //Suma las componentes reales de x e y
z.imag = x.imag + y.imag; //Suma las componentes imaginarias de x e y
complejo resta(complejo x, complejo y) //calcula la resta de dos
complejos
{
complejo z;
z.real = x.real - y.real; //Resta las componentes reales x e y
z.imag = x.imag - y.imag; //Resta las componentes imaginarias de x e y
return z; //Devuelveun opjeto complejo
}

2.
#include <iostream>
#include <stdlib.h>
using namespace std;
struct complejo {
float real;
float imag;
complejo suma (complejo x, complejo y);
complejo resta (complejo x, complejo y) ;
// A diferencia del programa 1, se inicializan las variables complejas
int main{} // Estructura_Conplejos_2.cpp
complejo x = {1,2 } ,y = {2,3}, z;//Inicializando los complejos x, y
z = suma (x, y);
cout << "\nLa suma es ; "<< z.real << " + "
<<z.imag <<"i"<< endl;
cout <<"\nLa resta es : "<< z.real << " + "
<<z.imag <<"i"<< endl;
return O ;

{
complejo suma (comple x, complejo y)
}

complejo z;
z. real = x. real + y. real;
z. imag = x. inag + y. imag;
return z ;
{
complejo resta (complejo x, complejo y) //Ca1cu1a la resta de dos complejos
}

complejo z;
z. real = x. real - y. real; // Resta Las componentes reales de x e y
z. imag = x. inag - y. imag; // Resta las componentes de x e y

return Z; // Devuelve un objeto complejo

}
3.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

struct punto { ;
float x;
float y;
};
double (punto pl, punto p2); // recibe dos variables punto
void printPunto (punto pl) ;
int main() // Estructura_Punto_I.cpp
{
punto pl = {1,1}, p2 = {2,2};
printPunto (pl) ; printPunto(p2) ;
double distancia;
distancia modulo (pl,p2) ;
cout<<"\nLa distancia es :
"<<sew(10)<<setprecision(7)<<distancia<<endl;
retuzn O ;
}
double modulo (punto pl, punto p2)
{// Retorna la distancia
return sgrt (pow (pl.x-p2.x,2) +pow(pl.y-p2.y,2);
}
void printPunto (punto p)
{
cout <<"\nPunto p( "<<p.x<<", " <<P.Y<<")"<<endl;
}
4.
#include <iostream>
# include <stdio.h> // para gets ( )
using namespace std ;
struct Producto {
char nombre[30];
char fabricante[30];
int cantidad;
float precio_unitario;
}
int main() // Estructura Producto _ I . cpp
{
Producto p;
float valor total; // valor total de los productos
cout<<"\nIngreso de datos:"<<endl;
// Leer el nombre del producto
cout<<"\nNombre del Producto �> ";
gets(p.nombre) ;
// Leer el nombre del fabricante
cout<<"\nNombre del Fabricante "
gets (p.fabricante) ;
// leer el numero de productos
cout<<"Numero de productos -> ";
cin>>p.cantidad;
// leer el precio unitario
cout<<"Precio de cada producto ->";
valor_total = p.cantidad*p.precio_unitario;
cout<<"\nProducto\t"<<p.nombre<<endl;
cout<<"Fabricante\t"<<p.fabricante<<endl;
cout<<"Precio unitario\t"<<p.precio_unitario\<<endl;
cout<<"Cantidad\t"<<p.cantidad<<endl;
cout<<"Valor total\t"<<valor_total<<endl;
return 0;
}

5.
#include <iostream>
# include <stdio.h> // para gets ( )
using namespace std ;
struct Producto {
char nombre[30];
char fabricante[30];
int cantidad;
float precio_unitario;
};
void LeeProductc(producto &p) ; // paso por referencia
void Resultado(Eroducto p);

int main()
{
Producto p;
LccProduct(p)
Resultado(p)
return 0;
}
void leeProductos(Producto &p)
{
cout<<"\nIngreso de datos:"<<endl;
// Leer el nombre del producto
cout<<"\nNombre del Producto -> ";
gets(p.nombre) ;
// Leer el nombre del fabricante
cout<<"\nNombre del Fabricante "
gets (p.fabricante) ;
// leer el numero de productos
cout<<"Numero de productos -> ";
cin>>p.cantidad;
// leer el precio unitario
cout<<"Precio de cada producto -> ";
cin<<p.precio_unitario;
}

void Resultado(Producto p)
{
float valor total; // valor total de los productos
//calcular el valor total
valor_total = p.cantidad*p.precio_unitario;
cout<<"\nProducto\t"<<p.nombre<<endl;
cout<<"Fabricante\t"<<p.fabricante<<endl;
cout<<"Precio unitario\t"<<p.precio_unitario\<<endl;
cout<<"Cantidad\t"<<p.cantidad<<endl;
cout<<"Valor total\t"<<valor_total<<endl;
}
6.
/*Objetivo: Una esteuctura anidada*/
#include <iostream>
# include <stdio.h> // para gets ( )
int dia, mes, year;
};
struct Producto {
char nombre[40];
short edad;
fecha fNac; //este campo es a su vez una estructura
char direccion[45];
char ocupacion[20];
};
void LeePersona(producto &p) ; // paso por referencia
void imprimePersona(persona p);
using namespace std ;

int main() //Estructura_persona_1.cpp


{
struct Producto p1;
LeerPersona(p1);
imprimirPersona(p1);
return 0;
}
void leePersona(Persona&p)
{
cout<<"\nLectura de datos de la persona:"<<endl;
cout<<"Ingrese nombre: "; gets(p.nombre) ; fflush(stdin);
cout<<"Ingrese la edad: " cin<<p.edad;
cout<<"Ingrese fecha de nacimiento: "; fflush(stdin);
cin>>p.fNac.dia>>;p.fNac.mes>>;p.fNac.year>>;
cout<<"Precio de cada producto -> "; fflush(stdin);
cout<<"ingrese direccion: "; gets(p.direccion); fflush(stdin);
cout<<"ingrese ocupacion: "; gets(p.ocupacion);
}

void imprimePersona(persona p)
{
cout<<"\nDatos de la persona:"<<endl;
cout<<"Nombre: " <<p.nombre<<endl;
cout<<"Edad: " <<p.edad<<endl;
cout<<"fecha de nacimiento: ";
cout>>p.fNac.dia>>"/"<<p.fNac.mes>>"/"<<p.fNac.year>>endl;
cout<<"Precio de cada producto -> "; fflush(stdin);
cout<<"direccion: "; puts(p.direccion); fflush(stdin);
7. cout<<"ocupacion: "; puts(p.ocupacion);
}

7.
/*Objetivo: Un arrays de estructuras*/
#include <iostream>
#include <stdio.h>
#include <string.h>
const int N = 50;
struct fecha{
int dia, mes, year;
};

struct persona{
char nombre[40];
short edad;
fecha fNac; //Este campo es a su vez una estructura
char direccion[45]
charocupacion[20];
};
//prototipo de las funciones
void LeerPersonas(persona &p);
void imprimePersonas(persona &p);
void LeerArrayPersonas(persona jov[], int n);
void imprimeArrayPersonas(persona jov[], int n);
void buscaPersona(persona jov[], int nom[]);
using namespace std;

int main()
{
persona jovenes[N]; //Declara un array de estructuras
int n;
cout<<"\nIngrese cantidad de personas: ";
con>>n;
LeerArrayPersonas(jovenes, n);
imprimeArrayPersonas(jovenes, n);
cout<<endl;
char nom[80];
cout<<"Ingrese nombre a buscar: "; gets(nom);
buscaPersona(jovenes, n, nom);
return 0;
}
void leePersona(Persona&p)
{
cout<<"\nIngrese nombre: "; gets(p.nombre) ; fflush(stdin);
cout<<"Ingrese la edad: " cin<<p.edad;
cout<<"Ingrese fecha de nacimiento: "; fflush(stdin);
cin>>p.fNac.dia>>;p.fNac.mes>>;p.fNac.year>>;
cout<<"ingrese direccion: "; gets(p.direccion); fflush(stdin);
cout<<"ingrese ocupacion: "; gets(p.ocupacion);
}

void imprimePersona(persona p)
{
cout<<"\nDatos de la persona:"<<endl;
cout<<"Nombre: " <<p.nombre<<endl;
cout<<"Edad: " <<p.edad<<endl;
cout<<"fecha de nacimiento(dd/mm/aaaa): ";
cout>>p.fNac.dia>>"/"<<p.fNac.mes>>"/"<<p.fNac.year>>endl;
cout<<"Precio de cada producto -> "; fflush(stdin);
cout<<"direccion: "; puts(p.direccion); fflush(stdin);
cout<<"ocupacion: "; puts(p.ocupacion);
}
void LeerArrayPersonas(persona jov[], int n);
{
cout<<<"Lectura de datos en e array de personas"<<endl;
for (int i=0;i<n;i++)
{ ffleush(stdin);
leerPersona(jov`[i])
}
}
void imprimeArrayPersonas(persona jov[], int m)
{
cout<<<"\nArray de personas"<<endl;
for (int i=0;i<n;i++)
imprimePersona(jov[i]);
}
void buscaPersona(persona jov[], int n, char nom[]);
{
bool existe = false; //se asume que no existe
strupr(nom); //pasando a mayuscular
for (int i=0; i<n; i++)
{
strupr(jov[i].nombre); //pasando a mayusculas
if (strcmp(jov[i].nombre,nom) == 0)
{
existe = true;
imprimePersona(jov[i]);
}
}
if (existe ==false)
cout << "Persona no existe!..."<<endl;
}

PARTE II: RECURSIVIDAD

La recursividad es uno de los tópicos mas elegantes de la ciencia de la computación, y es un


concepto muy importante en matemáticas, pues muchas definiciones se sustentan en la
recursividad.

Existe un conjunto de definiciones matemáticas que se plantean recursivamente, como por


ejemplo los números naturales, el cálculo del factorial de un número la sucesión de fibonacci,
la sucesión de ackerman, las definiciones de árboles, listas y otros

Ejemplos de definiciones recursivas

 Los números naturales: 0, 1, 2, 3,…

1) El cero de un número natural.


2) El suceso de un número natural es otro número natural, tal que n>0

 Las cadenas de caracteres.

1) El carácter nulo es una cadena.


2) El suceso de caracteres es un carácter seguido de otro carácter.

 Factorial recursivo

Dado un estero positivo n, el factorial de n se define como el producto de todos los enteros
entre n y 1. Por ejemplo, 4 factorial es igual a 4x3x2x1 = 24 y 3 factorial es igual a 3x2x1 = 6
y 2 factorial es 2x1 = 1. De otro lado 0 factorial se define como 1.

Utilizando notación matemática se puede escribir:

a) n!=1 si n=0

b) n!=n*(n-1) si n>0

Como puede observar en esta definición la factorial de un numero se define en términos de


sí mismo
Aplicando la definición recursiva para hallar 5! Se tiene:
(1) 5!=5*4!
(2) 4!=4*3¡
(3) 3!=3*2!
(4) 2!=2*1!
(5) 1!=1*0!
(6) 0!=1 Caso base!

Cada caso se reduce a un caso simple hasta llegar el caso de 0!, el cual es el caso base y
que por definición es 1. En la línea (6) el factorial de un número se define directamente y no
como en las líneas precedentes. Ahora recorriendo de la línea (6) a la línea (1) devolviendo
el valor computado en una línea para evaluar el resultado de la línea anterior se tiene
(6`) 0!=1
(5`) 1!=1*0!=1*1=1
(4`) 2!=2*1!=2*1=2
(3`) 3!=3*2!=3*2=6
(2`) 4!=4*3!=4*6=24
(1`) 5!=5*4!=5*24=120

 La serie de Fibonacci: 0, 1, 2, 3, 5, 13, 21, 34


La sucesión de Fibonacci es la siguiente:

0, 1, 2, 3, 5, 13, 21, 34, 55,…

Donde cada elemento de esta secuencia es la suma de los dos anteriores, asi: 0+1=1, 1+1=
2, 1+2=3, 2+3=5,…

Si definimos fibo(0)=0, fibo(1)=1 y a partir de aquí continuamos se construye la definición


recursiva para la sucesión de Fibonacci:

a) fibo(n)=0 si n=0 o n=1


b) fibo(n)= fibo(n-2)+ fibo(n-1) si n>1

 La multiplicación recursiva de dos números naturales

El producto a*b; donde ay b son esteros positivos, se puede definir como a sumado así
mismo un numero de veces igual a b. Una definición recursiva es la siguiente:

a) a*b=a si b=1
b) a*b=a*(b-1)+a si b>1

Para evaluar 5*4 utilizando esta definición debemos primero evaluar 5*3 y entonces el
resultado agregarle 5. Para evaluar 5*3 debemos primero evaluar 5*2 y al resultado
agregarle5. Para evaluar 5*2 debemos primero evaluar 5*1 y luego agregarle 5. Pero 5*1
es 5; segñun la primera parte de la definición recursiva, entonces se tiene

5*4=5*3+5*2+5+5=5*1+5+5+5=5+5+5+5=20
 Potencia recursiva de un número.

En algoritmo recursivo para evaluar la potencia de un número elevado a un exponente(no


negativo) puede ser visto como:

𝑎) 1 𝑠𝑖 𝑛=0
𝑥{ 𝑛−1
𝑏) 𝑥∗𝑥 𝑠𝑖 𝑛>0

De allí que por ejemplo, para evaluar 24 se puede escribir como potencia(2,4) que es igual a
2*potencia(2,3) y este a su vez es igual a 2*potencia(2,2); etc. A continuaciónse presenta el
trazado de pila para la función potencia(2,4).

Potencia(2,4)=2* potencia(2,3)
Potencia(2,3)=2* potencia(2,2)
Potencia(2,2)=2* potencia(2,1)
Potencia(2,1)=2* potencia(2,0)
Potencia(2,0)=1
Potencia(2,1)=2*1 =2
Potencia(2,2)=2*2 =4
Potencia(2,3)2*4=8
Potencia(2,4)=2* 8=16

 Maximo común divisor de dos números.

El máximo común divisor de dos números enteros puede definirse recursivivamente mediante la
siguiente relación de recurrencia:

𝑦 𝑠𝑖 (𝑦 ≤ 𝑥 𝑎𝑛𝑑 𝑥𝑚𝑜𝑑 𝑦 = 0)
𝑚𝑐𝑑(𝑥, 𝑦) = { 𝑚𝑐𝑑(𝑦, 𝑥) 𝑠𝑖 𝑥 < 𝑦
𝑚𝑐𝑑(𝑦, 𝑥 𝑚𝑜𝑑 𝑦) 𝑒𝑛 𝑜𝑡𝑟𝑜 𝑐𝑎𝑠𝑜

Resumiendo: Toda definición recursiva posee dos partes:

1) Caso base
2) Caso general que se acerca siempre al caso base para asegurarse que el algoritmo
termine en algún momento y se llama así misma.

Ejemplos:

8.

#include <iostream>
using namespace std;
//factorial recursivo
float fact(intn);
int main() //recurl.cpp
{
int n;
cout<<"\nIngrese n : ";
cin>>n
cout<<"\nEl factorial de "<<n<<"es: "<<fact(n)<<endl;
return 0;
}
float fact(int n)
{
if (n==0) //caso base
retutn 1;
else //caso general
return n*fact(n-1); //la funcion se llama asi misma
}

9.
#include <stdio.h>
#include <iostream>
using nanespace std;

// funcion fibonacci recursiva


float fibo(int n);

int main() //fibonacci_Recursiva.cpp


{
int n;
cout<<"\n.Ingrese n : ";
cin >> n;
cout<<"\nEl numero Fibonacci es: "<<fibo(n)<<endl;
}
float fibo(int n)
{
if(n == 0 || n == 1) //caso base
return n;
else //caso general
return (fibo(n-1) + fibo(n-2)); //llamada recursiva
}

10.
#include <iostream>
using nanespace std;
// multiplicacion a*b recursiva

int multrec(int a, intb);

int main() //Multiplica_Recursiva.cpp


{
int a, b;
cout<<"Ingrese dos enteros : ";
cin >> a>>b;
cout<<"\nEl producto es: "<<multrec(a,b)<<endl;
}
int multrec(int a, int b)
{
if(b == 1) //caso base
return a;
else //caso general
return (a+multrec(a, b-1));
}
11.
#include <iostream>
using nanespace std;
// funcion recursiva potencia c a la y
float potenrec(float x, int n);
int main() //Potencia_Recursiva.cpp
{
int x, n;
cout<<"\nIngrese base y exponente enteros positivos: ";
cin >> x>>n;
cout<<endl<<x<<" a la "<<n<<"multrec(x,n)<<endl;
return 0;
}
float potenrec(float x, int n)
{
if(b == 0) //caso base
return 1;
else //caso general
return (x*potenrec(x, n-1)); //llamada recursiva
}

12.
#include <iostream>
using nanespace std;
// funcion que suma recursivamente los elementos de un array
int sumarec(int a[], int n);
int main() //Suma_Array_Recursivo.cpp
{
int a[]={1,2,3,4,5,6};
int n = sizeof(a)/sizeof(int);
cout<<"\nSuma de elementos = "<<"sumarec(a,n)<<endl;
cin >> x>>n;
return 0;
}
int sumarec(int a[], int n)
{
if(n == 1) //caso base
return [0];
else //caso general
return (a[n-1] + sumarec(a, n-1)); //llamada recursiva
}

13.
#include <iostream>
#include <stdio.h> //para getchar()
using nanespace std;
// cuenta recursivamente la ocurrencia de un caracter en una cadena
int contador(char ch, char []);
int main() //Cuenta_Caracter_Recursivo.cpp
{
char ch, s[80];
cout<<"Ingrese cadena: ";
cin.getline(s, 870);
cout<<"\nIngrese caracter a contar : ";
ch = getchar(); //leer caracter desde la entrada
cout<<"\nCantidad de ocurrencias del caracter "<< ch <<"="
<<contador(ch, s)<<endl;
return 0;
}
int contador(char ch, char s [])
{
if(s[] == '\0') //caso base
return 0;
else //caso general
if(ch == s[0]) //si hay ocurrencia
return 1 + contador(ch, $s[1]);
else
return contador(ch, $s[1]);
}
14.
#include <iostream>
using nanespace std;
const int MAX = 30;

// encuentre recursivamente el maximo elemento de un array


int maximo(int x[], int n);

int main() //Maximo_Valor_Array.cpp


{
int x[MAX], n;
cout<<"\nCuantos elementos en el array? ";
cin >> n;
cout<<"\nIngrese "<<n<<" enteros en el array? ";
for (int i = 0; i<n ; i++)
cin>>x[1];
cout<<"\nEl maximo elemento es: "<<maximo(x, n)<<endl;
return 0;
}
int maximo(int x[], int n)
{
if(n == 1) //caso base
return x[0];
if(x(n-1) > maximo(x, n-1);
return x[n-1]
else
return maximo(x, n-1);
}

15
// Funcion recursiva para imprimir una frase al reves
#include <iostream>
#include <stdio.h> //para putchar
#include <string.h> //para strlen
using nanespace std;
void reversa_frase(char *s);
int main() //Cadena_Reversa_Recursivo.cpp
{
char s[] = "AMOR QUE BELLO ES AMARTE";
cout<<"\nCadena original: "<<s<<endl;
cout<<"\nCadena en reversa : ";
reserva_frase(s);
cout<<endl;
return 0;
}
void reversa_frase(char *s)
{
if(strlen(s)>1)
reversa_frase(&s[1]);
putchar(s[0]);
}