C# - Estructuras dinámicas: Listas tipo Pila - Problema de aplicación

Iniciado por Nolohagan, 13 Julio 2016, 13:22 PM

0 Miembros y 1 Visitante están viendo este tema.

Nolohagan

Hola,
queria hacer un programa que desarrolle una clase que tenga las siguientes responsabilidades (clase Formula):

- Ingresar una fórmula que contenga paréntesis, corchetes y llaves.
- Validar que los ( ) [] y {} estén correctamente balanceados.

La cosa es que hay cosas que no entiendo en el codigo.

Asi se ve en Form1.cs [Diseno]*:


Asi se ve en Pila.cs (hay que hacer una nueva clase):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Formula
{
    class Pila
    {
        class Nodo
        {
            public char simbolo;
            public Nodo sig;
        }

        private Nodo raiz;

        public Pila()
        {
            raiz = null;
        }

        public void Insertar(char x)
        {
            Nodo nuevo;
            nuevo = new Nodo();
            nuevo.simbolo = x;
            if (raiz == null)
            {
                nuevo.sig = null;
                raiz = nuevo;
            }
            else
            {
                nuevo.sig = raiz;
                raiz = nuevo;
            }
        }

        public char Extraer()
        {
            if (raiz != null)
            {
                char informacion = raiz.simbolo;
                raiz = raiz.sig;
                return informacion;
            }
            else
            {
                return char.MaxValue;
            }
        }

        public bool Vacia()
        {
            if (raiz == null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}


Y asi se ve en Form1.cs:

using Formula;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Formula
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Pila pila1;
            pila1 = new Pila();
            string cadena = textBox1.Text;
            for (int f = 0; f < cadena.Length; f++)
            {
                if (cadena.ElementAt(f) == '(' || cadena.ElementAt(f) == '[' || cadena.ElementAt(f) == '{')
                {
                    pila1.Insertar(cadena.ElementAt(f));
                }
                else
                {
                    if (cadena.ElementAt(f) == ')')
                    {
                        if (pila1.Extraer() != '(')
                        {
                            Text = "Incorrecta";
                            return;
                        }
                    }
                    else
                    {
                        if (cadena.ElementAt(f) == ']')
                        {
                            if (pila1.Extraer() != '[')
                            {
                                Text = "Incorrecta";
                                return;
                            }
                        }
                        else
                        {
                            if (cadena.ElementAt(f) == '}')
                            {
                                if (pila1.Extraer() != '{')
                                {
                                    Text = "Incorrecta";
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            if (pila1.Vacia())
            {
                Text = "Correcta";
            }
            else
            {
                Text = "Incorrecta";
            }
        }
    }
}


La cosa que no entiendo esta en Form1.cs. Aqui:



if (cadena.ElementAt(f) == ')')
                    {
                        if (pila1.Extraer() != '(')
                        {
                            Text = "Incorrecta";
                            return;
                        }
                    }


Dijimos si en alguna parte hay un ) (if (cadena.ElementAt(f) == ')')) entonces if (pila1.Extraer() != '('). Pero porque? Porque hace falta preguntar si no hay un ( si ya preguntamos si no hay un )?

Gracias y saludos

ivancea96

Si encuentras un elemento de cierre ], ) o }, entonces justo antes debe haber el mismo elemento, pero de apertura: [, ( o { respectivamente.
Si encontramos uno de cierre, entonces en la la cima de la pila, ha de estar el de apertura.

Con el segundo if, compruebas que esté el de apertura. Si no está, es que hay algo incorrecto.

Nolohagan

Hola ivancea96,
hay varias cosas que no entiendo en tu respuesta.
La primera es esta:

Citar
Si encuentras un elemento de cierre ], ) o }, entonces justo antes debe haber el mismo elemento, pero de apertura: [, ( o { respectivamente.

Pero con la formula (2+[3-12]*{8/3}) seria imposible esto. Ya que ( esta a un extremo de ), que esta en el otro extremo.

Gracias y saludos

ivancea96

Vale, expliqué mal la primera línea. Ignórala xD
La segunda sí. Cada vez que encuentras uno de apertura, lo metes en la pila. Luego, por cada uno de cierre, miras que esté en la pila (en la cima).

Nolohagan

Hola ivancea96,

Citar
Luego, por cada uno de cierre, miras que esté en la pila (en la cima).

Pero no entiendo. Eso es lo que pasa aqui?:

if (pila1.Extraer() != '(')
                        {
                            Text = "Incorrecta";
                            return;
                        }


Me puedes explicar, como si le explicases a un tonto, lo que pasa aqui por favor?:


if (cadena.ElementAt(f) == ')')
                    {
                        if (pila1.Extraer() != '(')
                        {
                            Text = "Incorrecta";
                            return;
                        }


Gracias y saludos

ivancea96

Sí, eso pasa ahí. Si no es el contrario, da error.

Primero, mira el siguiente caracter. Si es ')', entra. Si hay un ')', es que tuvo que haber antes un '(', y no pudieron quedar otros abiertos en medio.

Por ejemplo:
"([])"
La pila iría así:
"("
"(["
"("
""

Sin embargo, con:
"([)]"
"("
"(["
     <--- Aquí, btiene un ')'. Como el que hay en la pila, '[', no es el inverso, es que están mal cerrados.

Ponte un ejemplo pequeño y ve paso a paso, y lo verás en seguida.