Las pilas son estructuras de datos fundamentales que se utilizan en una variedad de aplicaciones en informática y programación. A continuación, exploraremos algunas de las aplicaciones más comunes de las pilas, proporcionando ejemplos y ejercicios para reforzar el aprendizaje.

  1. Evaluación de Expresiones

Expresiones Postfijas (Notación Polaca Inversa)

Las pilas se utilizan para evaluar expresiones aritméticas en notación postfija (RPN, Reverse Polish Notation). En RPN, los operadores siguen a sus operandos, lo que elimina la necesidad de paréntesis para definir el orden de las operaciones.

Ejemplo:

La expresión infija 3 + 4 * 2 / (1 - 5) se convierte en la expresión postfija 3 4 2 * 1 5 - / +.

Evaluación usando una pila:

  1. Leer el símbolo de la expresión postfija.
  2. Si el símbolo es un operando, apilarlo.
  3. Si el símbolo es un operador, desapilar los operandos necesarios, aplicar el operador y apilar el resultado.
def evaluate_postfix(expression):
    stack = []
    for char in expression.split():
        if char.isdigit():
            stack.append(int(char))
        else:
            b = stack.pop()
            a = stack.pop()
            if char == '+':
                stack.append(a + b)
            elif char == '-':
                stack.append(a - b)
            elif char == '*':
                stack.append(a * b)
            elif char == '/':
                stack.append(a / b)
    return stack.pop()

# Ejemplo de uso
expression = "3 4 2 * 1 5 - / +"
print(evaluate_postfix(expression))  # Salida: 1.0

Ejercicio:

Convierte la expresión infija 5 + ((1 + 2) * 4) - 3 a notación postfija y evalúala usando una pila.

Solución:

Expresión postfija: 5 1 2 + 4 * + 3 -

expression = "5 1 2 + 4 * + 3 -"
print(evaluate_postfix(expression))  # Salida: 14

  1. Verificación de Paréntesis Balanceados

Las pilas se utilizan para verificar si los paréntesis en una expresión están balanceados. Esto es útil en compiladores y editores de texto.

Ejemplo:

def are_parentheses_balanced(expression):
    stack = []
    for char in expression:
        if char in "({[":
            stack.append(char)
        elif char in ")}]":
            if not stack:
                return False
            top = stack.pop()
            if char == ')' and top != '(':
                return False
            elif char == '}' and top != '{':
                return False
            elif char == ']' and top != '[':
                return False
    return not stack

# Ejemplo de uso
expression = "{[()()]}"
print(are_parentheses_balanced(expression))  # Salida: True

Ejercicio:

Verifica si la expresión [(]) tiene paréntesis balanceados.

Solución:

expression = "[(])"
print(are_parentheses_balanced(expression))  # Salida: False

  1. Deshacer y Rehacer en Editores de Texto

Las pilas se utilizan para implementar las funcionalidades de deshacer (undo) y rehacer (redo) en editores de texto.

Ejemplo:

class TextEditor:
    def __init__(self):
        self.text = ""
        self.undo_stack = []
        self.redo_stack = []

    def write(self, text):
        self.undo_stack.append(self.text)
        self.text += text

    def undo(self):
        if self.undo_stack:
            self.redo_stack.append(self.text)
            self.text = self.undo_stack.pop()

    def redo(self):
        if self.redo_stack:
            self.undo_stack.append(self.text)
            self.text = self.redo_stack.pop()

# Ejemplo de uso
editor = TextEditor()
editor.write("Hola")
editor.write(" Mundo")
print(editor.text)  # Salida: Hola Mundo
editor.undo()
print(editor.text)  # Salida: Hola
editor.redo()
print(editor.text)  # Salida: Hola Mundo

Ejercicio:

Implementa una función delete en la clase TextEditor que permita eliminar los últimos n caracteres y soporte las operaciones de deshacer y rehacer.

Solución:

class TextEditor:
    def __init__(self):
        self.text = ""
        self.undo_stack = []
        self.redo_stack = []

    def write(self, text):
        self.undo_stack.append(self.text)
        self.text += text

    def delete(self, n):
        self.undo_stack.append(self.text)
        self.text = self.text[:-n]

    def undo(self):
        if self.undo_stack:
            self.redo_stack.append(self.text)
            self.text = self.undo_stack.pop()

    def redo(self):
        if self.redo_stack:
            self.undo_stack.append(self.text)
            self.text = self.redo_stack.pop()

# Ejemplo de uso
editor = TextEditor()
editor.write("Hola Mundo")
editor.delete(5)
print(editor.text)  # Salida: Hola
editor.undo()
print(editor.text)  # Salida: Hola Mundo
editor.redo()
print(editor.text)  # Salida: Hola

Conclusión

Las pilas son una estructura de datos versátil y poderosa que se utiliza en una variedad de aplicaciones, desde la evaluación de expresiones hasta la implementación de funcionalidades de deshacer y rehacer en editores de texto. Comprender estas aplicaciones no solo mejora tus habilidades de programación, sino que también te prepara para resolver problemas complejos de manera eficiente.

En el siguiente módulo, exploraremos las colas, otra estructura de datos fundamental con sus propias aplicaciones y características únicas.

© Copyright 2024. Todos los derechos reservados