Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Pila: estructura lineal de tipo LIFO (Last Input First Output: el último en entrar es el primero en salir).
Pila: capacidad, tope, elementos; ver si está vacía, ver si está llena, apilar, desapilar, ver el elemento que está en el
tope.
Ejemplo de aplicación de las pilas: evaluación o verificación de expresiones posfijas.
Cuando en la expresión encuentro una variable o una constante numérica, la coloco en la pila.
Cuando encuentro un operador, ya que estamos hablando de operadores binarios,
retiro los dos últimos elementos de la pila para hacer la operación
(el primer elemento retirado sería el segundo operando)
Si hay menos de dos elementos en la pila, la expresión es inválida.
El resultado de la operación se coloca en la pila.
Al final, la pila debe estar vacía. Si no lo está, la expresión es inválida.
“a b c + d e - * f / +”:
“a b c + - d - * e f +”: expresión inválida
“a b c + - d e f / +”: expresión inválida
}
}
// VERSIÓN 1
bool verificarSignosDeAgrupacion(Cola<char> *formulaPtr) {
Pila<char> pila;
while(!formulaPtr->estaVacia()) {
char caracter = formulaPtr->desencolar();
return pila.estaVacia();
}
// VERSIÓN 1
bool sonSignosDeAgrupacionCorrespondientes(char apertura, char cierre) {
if((apertura == ‘(’ && cierre == ‘)’) || (apertura == ‘[’ && cierre == ‘]’) || (apertura == ‘{’ && cierre == ‘}’)) {
return true;
}
else {
return false;
}
}
// VERSIÓN 2
bool sonSignosDeAgrupacionCorrespondientes(char apertura, char cierre) {
return (apertura == ‘(’ && cierre == ‘)’) || (apertura == ‘[’ && cierre == ‘]’) || (apertura == ‘{’ && cierre == ‘}’)
}
Pila<char> pila;
if(!sonSignosDeAgrupacionCorrespondientes(pila.desapilar(), caracter)) {
formulaBalanceada = false;
}
}
}
// VERSIÓN 2
bool sonSignosDeAgrupacionCorrespondientes(char apertura, char cierre) {
return (apertura == ‘(’ && cierre == ‘)’) || (apertura == ‘[’ && cierre == ‘]’) || (apertura == ‘{’ && cierre == ‘}’)
}
// VERSIÓN 3
bool verificarSignosDeAgrupacion(Cola<char> *formulaPtr) {
bool formulaBalanceada = true;
Pila<char> pila();
// VERSIÓN 4 (OK)
bool verificarSignosDeAgrupacion(Cola<char> *formulaPtr) {
bool formulaBalanceada = true;
Pila<char> pila();
Pila<char> pila();
while(!formulaPtr->estaVacia()) {
char caracter = formulaPtr->desencolar();
ERRORES COMUNES
Usar variables sin declararlas e inicializarlas.
Usar variables fuera de alcance.
CLASE DEL 13 DE SEPTIEMBRE DE 2023
RECURSIVIDAD
Factorial de un número
5 !=5× 4 × 3 ×2 ×1=120
5 !=5× ( 4 × 3 ×2 ×1 )=5 × 4 !=120
{
1 , n=0
n != n
∏ i ,n> 0
i=1
Definición recursiva:
n !=
{n× ( n−1
1 , n=0
) ! , n> 0
La recursividad funciona gracias a la pila de llamadas. Cada vez que se llama a la función recursiva, se coloca un nuevo
registro de aplicación en la pila de llamadas.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << n << “! = ” << factorial(n) << endl;
return 0;
}
numero: 0 return 1
numero: 1 return 1*factorial(0) ⟹ return 1*1 ⟹ return 1
numero: 2 return 2*factorial(1) ⟹ return 2*1 ⟹ return 2
numero: 3 return 3*factorial(2) ⟹ return 3*2 ⟹ return 6
numero: 4 return 4*factorial(3) ⟹ return 4*6 ⟹ return 24
n:4 n! = 24
Fibonacci
Población de conejos suponiendo que los conejos nunca mueren, se reproducen a partir de los dos meses y siempre
tienen un par de conejos, macho y hembra.
fib ( n )=
{fib ( n−11 ,∧n=0∨ n=1
) + fib(n−2),∧n>1
unsigned long int fibonacci(unsigned int numero) {
if(numero <= 1) {
return 1;
}
TAREAS
Construya una versión iterativa y eficiente del algoritmo de Fibonacci aplicando la técnica de diseño de algoritmos
Programación dinámica.
Construya una función recursiva que reciba como argumento un número entero no negativo y retorne la suma de las
cifras de dicho número.
// VERSIÓN 1
// La complejidad espacial de este algoritmo es de orden lineal (o de orden n).
unsigned long int obtenerEnesimoTerminoFibonacci(unsigned int n) {
unsigned long *fib = new unsigned long[n + 1];
fib[0] = 1;
fib[1] = 1;
delete [] fib;
return f_n;
}
f_0 = f_1;
f_1 = f_2;
}
return f_2;
}
Existen 10 clases de personas: las que saben binario y las que no.
Existen 3 clases de personas: las que saben contar y las que no.
// VERSIÓN 1
string convertirDecimal2cadenaBinaria(unsigned long int numero) {
if(numero < 2) {
return numero == 1 ? “1” : “0”;
}
// VERSIÓN 2
string convertirDecimal2cadenaBinaria(unsigned long int numero) {
if(numero < 2) {
return (numero == 1) ? “1” : “0”;
}
{
0 , n=0
1 ,n=1
binario ( n )= binario ()
n
2
+ 1 ,n> 1∧ 2∤ n
binario ()
n
2
+ 0 ,n> 1∧ 2∨n
TALLER
Construya una función recursiva que busque un valor en un vector y retorne la posición de la primera aparición de
dicho valor en el vector (-1 en caso de que no se encuentre). La función debe ser lo más eficiente posible.
En el main: cout << buscar(new int[] {-5, -2, 0, 4, 8, 12, 16, 21, 32, 40}, 10, 30);
// FUNCIÓN RECURSIVA:
// pre: para todo i < j: arreglo[i] <= arreglo[j]
// pre: inicial <= final
// Esta función busca en el subarreglo que va desde inicial hasta final.
int buscar(int arreglo[], int inicial, int final, int valorBuscado) {
TAREA
Construya la versión iterativa de la función del taller.
// pre: para todo i < j: arreglo[i] <= arreglo[j]
int buscar(int arreglo[], int longitud, int valorBuscado) {
Construya una clase en C++ que represente una lista de enteros sin datos repetidos y ordenada ascendentemente.
Implemente la clase como una lista simplemente enlazada.
TAREA: hacer funcionar el código.
TAREA: mejorar la clase para que funcione con cualquier tipo de dato. También incluya el manejo de excepciones.
class Nodo {
public:
int dato;
Nodo* siguiente;
Nodo(int dato) {
this.dato = dato;
this.siguiente = nullptr;
}
};
class ListaOrdenadaDeEnteros {
private:
Nodo *cabezaPtr;
bool permitirRepetidos;
public:
// TAREA: destructor, método eliminar, método mostrar, buscar.
ListaOrdenadaDeEnteros(bool permitirRepetidos);
~ListaOrdenadaDeEnteros();
};
ListaOrdenadaDeEnteros::ListaOrdenadaDeEnteros(bool permitirRepetidos) {
cabezaPtr = nullptr;
this.permitirRepetidos = permitirRepetidos;
}
// VERIFICAR QUE FUNCIONA PARA TODOS LOS CASOS: cuando la lista está vacía, cuando tiene un solo elemento,
cuando voy a insertar un elemento menor que el primero, cuando voy a insertar un elemento mayor que el último,
cuando voy a insertar un elemento que está entre el primero y el último, cuando voy a insertar elementos que ya
están en la lista y se permiten repetidos (igual al primero, igual al último, igual a un elemento intermedio) o cuando
no se permiten repetidos.
// TAREA: modificar el código para que los elementos repetidos queden en orden de inserción.
void ListaOrdenadaDeEnteros::insertar(int dato) {
// Creamos el nuevo nodo
Nodo *nuevoPtr = new Nodo(dato);
// Realizamos la inserción
if(anteriorPtr == nullPtr) {
cabezaPtr = nuevoPtr;
nuevoPtr->siguiente = actualPtr;
}
else {
anteriorPtr->siguiente = nuevoPtr;
nuevoPtr->siguiente = actualPtr;
}
}