sábado, 15 de junio de 2013

NOTACION POLACA

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


  class PILA <T>
    {   //ATRIBUTOS
        T[] vec;
        int tam;
        int tope;
        bool vacia;
        bool llena;

        //METODOS
        public PILA(int n)
        {
            tam = n;
            vec = new T[tam];
            tope = 0;
            vacia = true;
            llena = false;
        }

        public void Push(T valor)
        {
            vacia = false;
            vec[tope++] = valor;
            if (tope == tam)
                llena = true;
        }

        public T Pop()
        {
            llena = false;
            if (--tope == 0)
            {
                vacia = true;
            }
            return vec[tope];
        }

        public bool esta_Vacia()
        {
            return vacia;
        }

        public bool esta_Llena()
        {
            return llena;
        }

        public T Tope()
        {
            return vec[tope - 1];
        }
        public bool Full
        {
            //Si tope == pila.Length - 1, la pila esta llena
            get { return tope == vec.Length; }
        }

        public bool Empty
        {
            //Si tope == 0, la pila esta vacia
            get { return tope == 0; }
        }
        public int Length
        {
            //Regrersamos el tamaño del arreglo
            get { return vec.Length; }
        }
    }
======================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


public class Not_Polaca
{
  public  enum Simbolo { OPERANDO, PIZQ, PDER, SUMARES, MULTDIV, POW };
    public StringBuilder convertir_pos(string Ei)
    {
        char[] Epos = new char[Ei.Length];
        int tam = Ei.Length;
        PILA<int> stack = new PILA<int>(tam);

        int i, pos = 0;
        for (i = 0; i < Epos.Length; i++)
        {
            char car = Ei[i];
            Simbolo actual = Tipo_y_Presendecia(car);
            switch (actual)
            {
                case Simbolo.OPERANDO: Epos[pos++] = car; break;
                case Simbolo.SUMARES:
                    {
                        while (!stack.Empty && Tipo_y_Presendecia((char)stack.Tope()) >= actual)
                        {
                            Epos[pos++] = (char)stack.Pop();
                        }
                        stack.Push(car);
                    } break;
                case Simbolo.MULTDIV:
                    {
                        while (!stack.Empty && Tipo_y_Presendecia((char)stack.Tope()) >= actual)
                        {
                            Epos[pos++] = (char)stack.Pop();
                        }
                        stack.Push(car);
                    } break;
                case Simbolo.POW:
                    {
                        while (!stack.Empty && Tipo_y_Presendecia((char)stack.Tope()) >= actual)
                        {
                            Epos[pos++] = (char)stack.Pop();
                        }
                        stack.Push(car);
                    } break;
                case Simbolo.PIZQ: stack.Push(car); break;
                case Simbolo.PDER:
                    {
                        char x = (char)stack.Pop();
                        while (Tipo_y_Presendecia(x) != Simbolo.PIZQ)
                        {
                            Epos[pos++] = x;
                            x = (char)stack.Pop();
                        }
                    } break;
            }
        }
        while (!stack.Empty)
        {
            if (pos < Epos.Length)
                Epos[pos++] = (char)stack.Pop();
            else
                break;
        }
        StringBuilder regresa = new StringBuilder(Ei);

        for (int r = 0; r < Epos.Length; r++)
            regresa[r] = Epos[r];
        return regresa;
    }
    public Simbolo Tipo_y_Presendecia(char s)
    {
        Simbolo simbolo;
        switch (s)
        {
            case '+': simbolo = Simbolo.SUMARES; break;
            case '-': simbolo = Simbolo.SUMARES; break;
            case '*': simbolo = Simbolo.MULTDIV; break;
            case '/': simbolo = Simbolo.MULTDIV; break;
            case '(': simbolo = Simbolo.PIZQ; break;
            case ')': simbolo = Simbolo.PDER; break;
            case '^': simbolo = Simbolo.POW; break;
            default: simbolo = Simbolo.OPERANDO; break;
        }
        return simbolo;
    }
}

========================================================================
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 WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
     

        Not_Polaca notacion;
       
        PILA<int> pileishon;
        public Form1()
        {
            InitializeComponent();
        }

      
        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
          
                }

        private void button1_Click_1(object sender, EventArgs e)
        {

            notacion= new Not_Polaca();
            if (textBox1.Text != " ")
            {
                textBox3.Clear();
                textBox2.Text = notacion.convertir_pos(textBox1.Text).ToString();
            }

           
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Text="4+(2+8)/2";
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
             pileishon = new PILA<int>(textBox2.Text.Length);
             try
             {
                 string cad = textBox2.Text;
                 for (int i = 0; i < cad.Length; i++)
                 {
                     if (cad[i] >= 48 && cad[i] <= 57)
                     {
                         int num = cad[i] - 48;
                         pileishon.Push(num);
                     }
                     else
                     {
                         int resp = 0;
                         int num1 = pileishon.Pop();
                         int num2 = num1;
                         num1 = pileishon.Pop();
                         switch (cad[i])
                         {
                             case '+': resp = num1 + num2;
                                 break;
                             case '-': resp = num1 - num2;
                                 break;
                             case '*': resp = num1 * num2;
                                 break;
                             case '/': resp = num1 / num2;
                                 break;
                             case '^':
                                 {
                                     resp = num1;
                                     int j = 1;
                                     while (j < num2)
                                     {
                                         resp = resp * num1;
                                         j++;
                                     }
                                 }
                                 break;
                         }
                         pileishon.Push(resp);
                         textBox3.Text = resp.ToString();
                     }
                 }
             }
             catch
             {
                 MessageBox.Show("si ingresaste variables no se podra arrojar el resultado.. solo funciona con constantes");
             }

        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            textBox1.Text = "4+(2+8)/2";
        }
    }

 }

2 comentarios:

  1. Evalúo [=-5^2] y me da error de variables sin contantes.

    Este fallo me recuerda a otro que tiene Excel y que ya comenté en otro post.

    Si se introduce [=-5^2] en una celda, da como resultado 25.

    Sin embargo [=-(5^2)] lo calcula bien y da -25.

    Y lo más curioso, si ponemos algo delante del signo [-], por ejemplo un cero [=0-5^2], lo calcula correctamente y da -25.

    Para Excel no es lo mismo b-a^2 que -a^2+b.

    Entiendo que el fallo es que en el segundo caso, eleva al cuadrado también el signo [-]. Si yo quisiera que lo hiciera, escribiria (-a)^2+b.

    Esto obliga al usuario a estar pendiente del orden de los elementos al escribir una ecuación.

    Por cierto también ocurre en OpenOffice, imagino que por mantener la compatibilidad con Excel.

    Por si lo logro arreglar te aviso.

    ResponderEliminar
  2. como convierto una expresion infija a una prefija ?

    ResponderEliminar