Colabora |
Graficar Funciones[por elMesero]
Fecha: 23/Mar/2009 (19-03-09)
|
IntroducciónAlgú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.
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. PosfijaVamos 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. Nota:
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. Espacios de nombres usados en el código de este artículo:(Clase) System.Math Sobre el Autor:
|
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
|