Colabora
 

Graficar Funciones

[por elMesero]

 

Fecha: 23/Mar/2009 (19-03-09)
Autor: Ricardo Bernave Llamocca Choquehuanca - [email protected]

 


Introducción

Algún día tenían que llegar la vacaciones, o bueno, dizque vacaciones, pues aun hay que ir a la U :s. Interesado un poco en como el Matemática u otros software de se las ingenian para graficar funciones ingresadas en modo texto, y dado que ahora tengo mas horas de vago, pues me puse a leer un poco sobre lo que es la notación Infija y Posfija.
Creo que estos términos son de conocimiento general, dado que también me enseñaron esto en la U, y ahora que lo necesito, pues abre de usarlo, gracias al profe Edwin Hinojosa, por esas clases que nos rompieron el coco. Comenzare dando un pequeño marco teórico de lo que es Infija y Posfija, aunque recomiendo busquen en el Google.

 

Infija:

Infija es como normalmente escribimos las funciones o formulas matemáticas, un ejemplo: 3+2-1, como verán, el operador se encuentra entre los operandos, obviamente cada operando tiene su prioridad, la división tiene mayor prioridad que una suma, la potencia mayor prioridad que la multiplicación y así sucesivamente, es por eso que nos resulta fácil a nosotros los humanos, entender y resolver estas formulas (jaja, aunque a veces nos toca copiar en los exámenes :P), pero para una computadora es mucho mas complejo, y mas aun si en esta formula incluimos variables, buscar prioridades o que operación debe de realizarse primero, se hace mas complejo, eh ahí que surge la notación Posfija y Prefija, de la cual solo escribiré brevemente de la Posfija.

Posfija

Vamos directamente al grano, en Infija se escribía = 3+2, en posfija se escribirá = 32+, esta notación es mucho mas facil de entender para un computador, dado que solo toma los dos campos antes del operador y realiza la operación.
Por hacer corta la explicación, omitiré la explicación de como pasar a Posfija. Pero dejare un ejemplo de como se analiza esta. INFIJA: a+b*c+(d*e+f)*g    POSFIJA: abc*+de*f+g*+

Nota:
El problema que existe con la notación infija, es que toma carácter por carácter, lo cual nos arrojaría un error a la hora de procesarlo, dado que no solo ingresaremos campos de un carácter. Ejm: Infija: 27+2 en Posfija: 272+, a la hora de analizar este campo, como subdividimos??, habrían 3 opciones 2+72 ó 27+2 ó +272.

 

El Código:

Como es de mi costumbre, solo pondré el código de los módulos, mas no del formulario, de igual manera, adjunto el código para que no haya reproches.

Funcion que nos sirve para evaluar la prioridad de los signos encontrados en la funcion

Private Function PrioridadSigno(ByVal Signo As String) As Integer
        PrioridadSigno = -1
        If Signo = "(" Or Signo = ")" Then
            PrioridadSigno = 0
            Return PrioridadSigno
        ElseIf Signo = "+" Or Signo = "-" Then
            PrioridadSigno = 1
            Return PrioridadSigno
        ElseIf Signo = "*" Or Signo = "/" Then
            PrioridadSigno = 2
            Return PrioridadSigno
        ElseIf Signo = "^" Then
            PrioridadSigno = 3
            Return PrioridadSigno
        End If
        Return PrioridadSigno
    End Function

Como dige en el apartado de arriba, existe un problema con el numero de digitos, esta funcion corrige ese problema

Private Function CuentaDigitosNumericos(ByVal Texto As String, ByVal Indice As Integer, ByVal Longitud As Integer) As Integer
        Dim Centinela As Boolean = False
        CuentaDigitosNumericos = 0
        While Indice <= Longitud - 1 And Centinela = False
            If IsNumeric(Texto(Indice)) Then
                CuentaDigitosNumericos = CuentaDigitosNumericos + 1
            ElseIf Texto(Indice) = "." Then
                CuentaDigitosNumericos = CuentaDigitosNumericos + 1
            Else
                Centinela = True
            End If
            Indice = Indice + 1
        End While
        Return CuentaDigitosNumericos
    End Function

Aqui analizamos la funcion INFIJA para convertila en una funcion POSFIJA

Public Function Posfija(ByVal Funcion As String, ByVal Longitud As Integer)
        Dim Pila(Longitud), pPosfija(Longitud) As Object
        Dim Tope, TopePosfija As Integer
        Dim Temporal As String
        Dim i, j As Integer

        Tope = 0
        TopePosfija = 0
        For i = 0 To Longitud - 1
            Temporal = Funcion(i)
            If Temporal = "(" Then
                Tope = Tope + 1
                Pila(Tope) = Temporal
            Else
                If Temporal = ")" Then
                    While Pila(Tope) <> "("
                        pPosfija(TopePosfija) = Pila(Tope)
                        TopePosfija = TopePosfija + 1
                        Tope = Tope - 1
                    End While
                    Tope = Tope - 1
                Else
                    If PrioridadSigno(Temporal) = -1 Then
                        For j = 2 To CuentaDigitosNumericos(Funcion, i, Longitud)
                            i = i + 1
                            Temporal = Temporal + Funcion(i)
                        Next j
                        pPosfija(TopePosfija) = Temporal
                        TopePosfija = TopePosfija + 1
                    Else
                        While ((Tope > 0) And (PrioridadSigno(Temporal) <= PrioridadSigno(Pila(Tope))))
                            pPosfija(TopePosfija) = Pila(Tope)
                            TopePosfija = TopePosfija + 1
                            Tope = Tope - 1
                        End While
                        Tope = Tope + 1
                        Pila(Tope) = Temporal
                    End If
                End If
            End If
        Next i
        While Tope > 0
            pPosfija(TopePosfija) = Pila(Tope)
            TopePosfija = TopePosfija + 1
            Tope = Tope - 1
        End While

        Return pPosfija
    End Function

Aqui Evaluamos los parametros del funcion POSFIJA para determinar el valor de la funcion

Public Function EvaluarPosfija(ByVal Posfija As Object, ByVal Variable As Double) As Double
        Dim Contador As Integer = 0
        Dim Centinela As Boolean = False
        Dim i As Integer

        EvaluarPosfija = 0
        While Centinela = False
            If Posfija(i) <> Nothing Then
                Contador = Contador + 1
            Else
                Centinela = True
            End If
            i = i + 1
        End While
        Centinela = False
        For i = 0 To Contador - 1
            If Posfija(i).ToString = "x" Or Posfija(i).ToString = "X" Then
                Posfija(i) = Variable.ToString
            End If
            If i > 1 Then
                Select Case Posfija(i).ToString
                    Case "+"
                        Posfija(i) = Val(Posfija(i - 2)) + Val(Posfija(i - 1))
                        Centinela = True
                    Case "-"
                        Posfija(i) = Val(Posfija(i - 2)) - Val(Posfija(i - 1))
                        Centinela = True
                    Case "*"
                        Posfija(i) = Val(Posfija(i - 2)) * Val(Posfija(i - 1))
                        Centinela = True
                    Case "/"
                        Posfija(i) = Val(Posfija(i - 2)) / Val(Posfija(i - 1))
                        Centinela = True
                    Case "^"
                        Posfija(i) = Pow(Val(Posfija(i - 2)), Val(Posfija(i - 1)))
                        Centinela = True
                    Case Else
                        Centinela = False
                End Select
                If Centinela = True Then
                    If (i - 4) > -1 Then
                        Posfija(i - 1) = Posfija(i - 3)
                        Posfija(i - 2) = Posfija(i - 4)
                    ElseIf (i - 3) > -1 Then
                        Posfija(i - 1) = Posfija(i - 3)
                    End If
                    Centinela = False
                End If
            Else
                Select Case Posfija(i).ToString
                    Case "+"
                        Posfija(i) = 0 + Val(Posfija(i - 1))
                    Case "-"
                        Posfija(i) = 0 - Val(Posfija(i - 1))
                    Case "*"
                        Posfija(i) = 0 * Val(Posfija(i - 1))
                    Case "/"
                        Posfija(i) = 0 / Val(Posfija(i - 1))
                    Case "^"
                        Posfija(i) = Pow(0, Val(Posfija(i - 1)))
                    Case Else
                        Centinela = False
                End Select
            End If
        Next i
        If Contador > 0 Then
            Return Val(Posfija(Contador - 1))
        Else
            Return Val(Posfija(Contador))
        End If

    End Function

 

Weno creo que como siempre, todo esta claro.
Uff pos hace un buen tiempo que no publicaba algo, no habia tiempo, ahora lo hay, pero da flojera :P, pronto volveran a saber de mi, eso denlo por hecho. Espacio de librerias usadas en el código de este artículo:



Espacios de nombres usados en el código de este artículo:

(Clase) System.Math
System.Drawing


Sobre el Autor:

Nombre: Ricardo Bernave Llamocca Choquehuanca

Alias: elMesero

e-Mail: [email protected]

Profesión: Aun de vago en la Universidad

 

 



Compromiso del autor del artículo con el sitio del Guille:

Lo comentado en este artículo está probado (y funciona) con la siguiente configuración:

El autor se compromete personalmente de que lo expuesto en este artículo es cierto y lo ha comprobado usando la configuración indicada anteriormente.

En cualquier caso, el Guille no se responsabiliza del contenido de este artículo.

Si encuentras alguna errata o fallo en algún link (enlace), por favor comunícalo usando este link:

Gracias.


Código de ejemplo (comprimido):

 

Fichero con el código de ejemplo: elMesero_GraficarFunciones_waGraficas.zip - 56.30 KB

(MD5 checksum: A6F98C6EF91619ED4058F17B3C5F2E20)

 


Ir al índice principal de el Guille