Notación polaca y usando pila con Template

namespace notacion_polaca
{
    enum Simbolo { OPERANDO, PIZQ, PDER, SUMRES, MULDIV, POW, };
    class Not_Polaca
    {
        int cuantosp;
        public Simbolo Tipo_y_Precedencia(char s)
        {
            Simbolo simbolo;
            switch(s)
            {
                case '+': simbolo = Simbolo.SUMRES; break;
                case '-': simbolo = Simbolo.SUMRES; break;
                case '/': simbolo = Simbolo.MULDIV; break;
                case '*': simbolo = Simbolo.MULDIV; break;
                case '^': simbolo = Simbolo.POW; break;
                case '(': simbolo = Simbolo.PIZQ; break;
                case ')': simbolo = Simbolo.PDER; break;
               
                default: simbolo = Simbolo.OPERANDO; break;
            }
            return simbolo;
        }
        public StringBuilder ConvertPosFija(string Ei)
        {
            cuantosp = 0;
            int tam = Ei.Length;
            char[] Epos = new char[tam];
            Pila<char> stack = new Pila<char>(tam);
            int i, pos = 0;
            for (i = 0; i < Epos.Length; i++)
            {
                char car =Ei[i];
                Simbolo actual = Tipo_y_Precedencia(car);
                switch (actual)
                {
                    
                    case Simbolo.OPERANDO: Epos[pos++] = car; break;
                     
                    case Simbolo.SUMRES:
                        {
                            while (!stack.Vacia && Tipo_y_Precedencia((char)stack.Tope()) >= actual)
                                Epos[pos++] = (char)stack.Pop();
                            stack.Push(car);
                        } break;
                      
                    case Simbolo.MULDIV:
                        {
                            while (!stack.Vacia && Tipo_y_Precedencia((char)stack.Tope()) >= actual)
                                Epos[pos++] = (char)stack.Pop();
                            stack.Push(car);
                        } break;
                
                    case Simbolo.POW:
                        {
                            while (!stack.Vacia && Tipo_y_Precedencia((char)stack.Tope()) >= actual)
                                Epos[pos++] = (char)stack.Pop();
                            stack.Push(car);
                        } break;
                  
                    case Simbolo.PIZQ:
                        {
                            stack.Push(car);
                            cuantosp++;
                        } break;


                
                    case Simbolo.PDER:
                        {
                            char x = (char)stack.Pop();
                            while (Tipo_y_Precedencia(x) != Simbolo.PIZQ)
                            {
                                Epos[pos++] = x;
                                x = (char)stack.Pop();
                            }
                        } break;
                }
            }
                while (!stack.Vacia)
                {//Porque esta ocasionando problemas con indice fuera de rango 
                    if (pos < Epos.Length)
                        Epos[pos++] = (char)stack.Pop();
                    else
                        break;
                }     
                StringBuilder regresa = new StringBuilder(Ei); //Epos.ToString();
                for (int r = 0; r < Epos.Length; r++)
                    regresa[r] = Epos[r];               
                return regresa;
            }
        public double ResolverPosFija(StringBuilder Epos)
        {
            Epos.Length -= cuantosp;
            int tam = Epos.Length;
            Pila<double> stack = new Pila<double>(tam);
            
            for (int i = 0; i < Epos.Length; i++)
            {
                char operador = Epos[i];
                double num = operador - 48;
                Simbolo actual = Tipo_y_Precedencia(operador);
                switch (actual)
                {
                    case Simbolo.OPERANDO: stack.Push(num); break;
                    case Simbolo.SUMRES:
                        {
                            if (operador == '+')
                            {
                                double num2 = stack.Pop();
                                stack.Push(stack.Pop() + num2);
                            }
                            else
                            {
                                double num1 = stack.Pop();
                                stack.Push(stack.Pop() + num1);
                            }
                        }break;
                    case Simbolo.MULDIV:
                        {
                            if (operador == '*')
                            {
                                double num2 = stack.Pop();
                                stack.Push(stack.Pop() * num2);
                            }
                            else
                            {
                                double num1 = stack.Pop();
                                stack.Push(stack.Pop() / num1);
                            }
                        }break;
                    case Simbolo.POW:
                        {
                            double num2 = stack.Pop();;
                            stack.Push(Math.Pow(stack.Pop(),num2));
                        }break;
                }
            }
            return stack.Pop();
        }
        public string AnalizarCadena(string Ei)
        {
            int pos=1;
            int tam = Ei.Length;
            string cad = "falta";
            for (int i = 0; i < tam; i++)
            {
                char car = Ei[i];
                while(pos <= tam)
                {
                    if (Ei[pos] != ')')
                        pos++;
                    else
                        cad += ")";
                }
            }
            return cad;
        }            
        }
    }
//----------------------------------------------------------

class Pila<T>
    {
        //Atributos
        T[] _pila;
        int tam;
        int tope;
        bool vacia;
        bool llena;
        //Constructores
        public Pila()
        {
            tam = 5;
            tope = 0;
            vacia = true;
            llena = false;
            _pila = new T[5];
        }
        public Pila(int MAX)
        {
            tam = MAX;
            tope = 0;
            vacia = true;
            llena = false;
            _pila = new T[MAX];
        }
        //Propiedades
        public bool Llena
        {
            get { return llena;}
        }
        public bool Vacia
        {
            get{return vacia;}
        }
        //Metodos
        public void Push(T dato)//Poner
        {
            vacia = false;
            _pila[tope++] = dato;
            if (tope == tam)
                llena = true;            
        }
        public T Pop()//Quitar
        {
            if (--tope == 0)
                vacia = true;
            llena = false;
            return _pila[tope]; 
        }
        public T Tope()
        {
            return _pila[tope - 1];
        }
    }

No hay comentarios:

Publicar un comentario