Autor
|
Tema: Lista de Operadores Matematicos (Leído 3,598 veces)
|
rigorvzla
Desconectado
Mensajes: 213
|
Hola a todos, estoy en un problema, creo una lista de tipo string, donde guardo los simbolos matematicos, (+) (-) (*) (/), quiero usarlos para que hagan su funcion de acuerdo a lo que pido, pero no encuentro como hacerlo. actualemnte esta asi calculo = calculo + Convert.ToInt32(valores[i]); pero lo necesito asi for{ calculo = calculo ListaSimbolo[i] Convert.ToInt32(valores[i]);} espero puedan ayudarme a resolver este problema
|
|
|
En línea
|
|
|
|
Serapis
|
Los operadores no son variables. ...pero, en .NET puedes sobrecargar los operadores o definir los propios.
Podrías implementar un operador 'Operar(x,y,z)', donde uno de los parámetros fuera precisamente el operador a utilizar (basado en una enumeración), los otros parámetros serían los propios del operador. en realidad equivaldría a una función donde pasas esos parámetros y allí mediante un 'select case' evalúa la expresión con el operador elegido.
La ventaja de definir e implementar un operador es que se puede usar de la manera concreta que precises.
|
|
|
En línea
|
|
|
|
Mr. NoBody
Desconectado
Mensajes: 20
"You Take The Red Pill - You Stay In Wonderland"
|
No pierdas el tiempo ni reinventes la rueda, utiliza un evaluador de expresiones matemáticas. O bien eliges utilizar la función Eval de javascript (mediante el motor de JS de .NET), o bien eliges utilizar la librería de terceros NCalc: Eval y NCalc son metodologías que implican un tiempo lento de inicialización, pero ambas son robustas, a prueba de fallos. Aquí puedes ver el sofisticado procedimiento de análisis o data parsing y compilación de una expresión matemática con NCalc: https://github.com/ncalc/.../NCalcParser. En general, evaluar expresiones con NCalc es bastante más rápido que con Eval, esto sobre todo se nota al medir el tiempo de ejecución cuando llevamos a cabo muchas operaciones de forma consecutivas en búcle, y en fin, es una solución open-source. Ejemplo propio en VB.NET para validar sintaxis, y evaluar expresión: ''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Validates the syntax of an arithmetic expression. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <example> This is a code example. ''' <code language="VB.NET"> ''' Dim expr As String = "1 + ABC" ''' Dim isValid As Boolean = ValidateExpression(expr) ''' </code> ''' </example> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' <see langword="True"/> if the arithmetic expression does not contain syntax errors, ''' otherwise, <see langword="False"/>. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- <DebuggerStepThrough> Public Shared Function ValidateExpression(expr As String) As Boolean Dim calc As New Global.NCalc.Expression(expr) If calc.HasErrors() Then Return False End If Try Decimal.TryParse(CStr(calc.Evaluate()), New Decimal) Return True Catch Return False End Try End Function
''' ---------------------------------------------------------------------------------------------------- ''' <summary> ''' Evaluate and return the result of an arithmetic expression. ''' </summary> ''' ---------------------------------------------------------------------------------------------------- ''' <example> This is a code example. ''' <code language="VB.NET"> ''' Dim expr As String = "(1 + (2 - 2)) * (100 / 2.5)" ' = 40 ''' Dim result As Decimal = EvaluateExpression(expr) ''' </code> ''' </example> ''' ---------------------------------------------------------------------------------------------------- ''' <returns> ''' The resulting value. ''' </returns> ''' ---------------------------------------------------------------------------------------------------- ''' <exception cref="Global.NCalc.EvaluationException"> ''' </exception> ''' ---------------------------------------------------------------------------------------------------- <DebuggerStepThrough> Public Shared Function EvaluateExpression(expr As String) As Decimal Dim calc As New Global.NCalc.Expression(expr) Dim result As Decimal If calc.HasErrors() Then Throw New Global.NCalc.EvaluationException(message:=calc.Error) Else Try result = CDec(calc.Evaluate()) Return result Catch ex As Global.NCalc.EvaluationException Throw Catch ex As ArgumentException Throw New Global.NCalc.EvaluationException(message:=ex.Message) Catch ex As Exception Throw End Try End If End Function
Importante: NCalc no se limita solamente a evaluar expresiones de tipos numéricos, sino que además puede evaluar otros tipos como DateTime y comparaciones de caracteres entre strings, pero las funciones ValidateExpression y EvaluateExpression del código de arriba funcionarán de forma correcta solamente con los tipos simples numéricos, es decir integrales o de punto flotante ( https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types#built-in-value-types ) ya que es el uso que se le pretende dar. Si prefieres hacerte el guiso por ti mismo, aquí tienes otras alternativas en C# (ordenados por fecha de antiguedad): Saludos.
|
|
« Última modificación: 9 Febrero 2021, 23:27 pm por Mr. NoBody »
|
En línea
|
|
|
|
Serapis
|
La solución que te ofrece Elek... digo el señor Nobody, es muy válida cuando tengas expresiones enteramente textuales, pero si el contenido procede de entresacar valores de alguna parte que vuelcas sobre un array, es preferible el método que te he descrito... también será más rápido. Te pongo un ejemplo, tu completa, corrige allí donde precises y haz los cambios que necesites... Primero el código de ejemplo... cuyo resultado arroja 45. (LaClaseDondeLoPongas hace referencia a una clase donde coloques el código de la siguiente sección) Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim v() As String, o() As String Dim resultado As Single ReDim v(0 To 4), o(0 To 4) v(4) = "5" : v(3) = "7" : v(2) = "11" : v(1) = "13" : v(0) = "17" o(4) = "/" : o(3) = "-" : o(2) = "+" : o(1) = "*" : o(0) = "+" resultado = LaClaseDondeLoPongas.Operandos.Totalizar(v, o) System.Windows.Forms.MessageBox.Show(resultado.ToString) End Sub
Y el código que realiza todo el trabajo: Public Structure Operandos Public Total As Single Private Operando As Integer Private Operador As Operadores Public Enum Operadores OPERADOR_SUMA = 0 OPERADOR_RESTA = 1 OPERADOR_MULTIPLICA = 2 OPERADOR_DIVIDE = 3 End Enum Public Shared Function Totalizar(ByRef Valores() As String, ByRef Operadores() As String) As Single Dim k As UInt32 Dim T As New Operandos Dim Resul As New Operandos ' NOTA: se supone que ambos arrays son igual de largos (el primer valor se considera 0, luego se entiende que el operador para el primer operando es '+'). ' Procesa un operando de cada vez, con el operador asociado sobre el total acumulado ' (si entendi mal deberas corregirlo a tus necesidades) For k = 0 To Valores.Length - 1 With T .Operando = Convert.ToInt32(Valores(k)) .Operador = ToOperador(Operadores(k)) .Total = Resul.Total Resul = (T = Resul) End With Next Return Resul.Total End Function Public Shared Operator =(ByVal XY As Operandos, ByVal R As Operandos) As Operandos With XY Select Case .Operador Case Operadores.OPERADOR_SUMA Try .Total += .Operando Catch ex As Exception System.Windows.Forms.MessageBox.Show(ex.Message) End Try Case Operadores.OPERADOR_RESTA Try .Total -= .Operando Catch ex As Exception System.Windows.Forms.MessageBox.Show(ex.Message) End Try Case Operadores.OPERADOR_MULTIPLICA Try .Total *= .Operando Catch ex As Exception ' desbordamiento, etc... System.Windows.Forms.MessageBox.Show(ex.Message) End Try Case Operadores.OPERADOR_DIVIDE Try .Total /= .Operando Catch ex As Exception ' division por 0, etc... System.Windows.Forms.MessageBox.Show(ex.Message) End Try End Select Return XY End With End Operator ' Declarar un operador '=' exige declarar tambien otro '<>' (aunque no lo usemos). Public Shared Operator <>(ByVal XY As Operandos, ByVal R As Operandos) As Operandos Return Nothing End Operator ' Resulta autoexplicativo... Private Shared Function ToOperador(ByVal Op As String) As Operadores Select Case Op.Trim Case "+" : Return Operadores.OPERADOR_SUMA Case "-" : Return Operadores.OPERADOR_RESTA Case "*" : Return Operadores.OPERADOR_MULTIPLICA Case "/" : Return Operadores.OPERADOR_DIVIDE End Select End Function End Structure
|
|
|
En línea
|
|
|
|
rigorvzla
Desconectado
Mensajes: 213
|
MUCHISIMAS MUCHISIMAS GRACIAS!!! Elektro mucho tiempo sin saber de ti, q bueno estas vivo aun jeje , ya me pondre con ello de inmediato a ver como optimizar el codigo , de todos modos les compartire la solucion que encontre de momento. for (int i = 0; i < valores.Length; i++) { string calc = $"{ListaSimbolos[i]}{valores[i]}"; if (calc.Contains("+")) { calculo = calculo + Convert.ToInt32(calc); } else if (calc.Contains("-")) { calculo = calculo + Convert.ToInt32(calc); } else if (calc.Contains("*")) { string ca = calc.Replace("*", " ").Trim(); calculo = Convert.ToInt32(calculo) * Convert.ToInt32(ca); }
else if (calc.Contains("/")) { string ca = calc.Replace("/", " ").Trim(); calculo = Convert.ToInt32(calculo) / Convert.ToInt32(ca); } } Explico de manera rapida, creo una lista de los signos que pido en su respectivo orden, luego obtengo cada numero y evaluo el simbolo que tiene cada valor para asi , ejecutar dicha operacion matematica, creanlo o no, me ha servido , pero si , con Ncalc simplifico esto estaria espectacular. Nuevamente gracias y me pondre con esto. saludos a todos los q me ayudaron, gracias.
|
|
|
En línea
|
|
|
|
Mr. NoBody
Desconectado
Mensajes: 20
"You Take The Red Pill - You Stay In Wonderland"
|
les compartire la solucion que encontre de momento. Si quieres micro-optimizar ese código entonces quizás podrías tratar de aplicar el ejemplo del usuario Serapis ya que ha invertido tiempo en hacerlo y es más completo o sofisticado que la solución actual que aplicaste, donde su ejemplo de usar Select Case / switch es más apropiado (y también más elegante, dicho sea de paso) que utilizar un bloque de condicionales else + contains ya que tienes un set de símbolos o valores fijos ( https://www.geeksforgeeks.org/switch-vs-else/ ). Además deberías intentar tener presente utilizar la asignación compuesta del operador de suma (+=) en tu variable "calculo" ( https://www.tutorialspoint.com/compound-assignment-operators-in-chash ), lo cual no optimiza el código pero simplifica bastante la comprensión del código fuente. De todas formas a mi no me convence el enfoque que ambos le dieron, en tu caso fíjate que al final estás tratanto con varias funciones de tratamiento de cadenas de texto como string.replace y string.trim, y luego haciendo distintas operaciones sobre un mismo valor numérico, para eso sería preferible que directamente lo simplificases construyendo un string completo con la expresión matemática y pasárselo a NCalc, pero bueno, por otro lado pienso que cualquier opción o solución es igual de válida mientras el resultado sea exitoso. pero si , con Ncalc simplifico esto estaria espectacular Poder se podría siempre y cuando le des el enfoque de construir un string / expresión matemática en lugar de hacerlo como lo estás haciendo actualmente, pero ya no merece la pena mientras tu código actual te funcione de forma exitosa no hay necesidad real de desecharlo o adaptarlo para hacer las cosas de forma distinta. Lo que yo te diría es que intentes considerar NCalc para futuras necesidades, por que te podrá venir de perlas. Saludos!
|
|
« Última modificación: 10 Febrero 2021, 23:42 pm por Mr. NoBody »
|
En línea
|
|
|
|
Tachikomaia
Desconectado
Mensajes: 1.208
Superhacker (es broma xD )
|
Yo veo un error en el "-". En los otros 3 símbolos se repiten 2 veces, pero en este caso hay un +.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Ayuda Matematicos!!!
« 1 2 »
Programación Visual Basic
|
IvanUgu
|
11
|
5,322
|
20 Diciembre 2008, 18:12 pm
por el_c0c0
|
|
|
Ejercicios matemáticos
Ejercicios
|
@synthesize
|
2
|
5,333
|
31 Diciembre 2009, 18:59 pm
por MIG80
|
|
|
Matemáticos, ¡os invoco!, pido su ayuda.
Foro Libre
|
ignorantev1.1
|
8
|
3,805
|
12 Marzo 2014, 17:24 pm
por programatrix
|
|
|
Siguen las multas a operadores que incluyen a clientes en la lista de morosos...
Noticias
|
wolfbcn
|
0
|
1,465
|
21 Mayo 2015, 21:46 pm
por wolfbcn
|
|
|
¿Cuáles son los operadores principales de España? La CNMC publica una lista ...
Noticias
|
wolfbcn
|
0
|
1,058
|
28 Noviembre 2018, 21:32 pm
por wolfbcn
|
|