Pregunta

Hola, me preguntaba si existe alguna forma conocida de eliminar paréntesis innecesarios en una fórmula matemática.La razón por la que hago esta pregunta es que tengo que minimizar la longitud de la fórmula.

if((-if(([V].[6432])=0;0;(([V].[6432])-([V].[6445]))*(((([V].[6443]))/1000*([V].[6448])
+(([V].[6443]))*([V].[6449])+([V].[6450]))*(1-([V].[6446])))))=0;([V].[6428])*
((((([V].[6443]))/1000*([V].[6445])*([V].[6448])+(([V].[6443]))*([V].[6445])*
([V].[6449])+([V].[6445])*([V].[6450])))*(1-([V].[6446])));

es básicamente parte de la declaración de selección de SQL.No puede superar los 255 caracteres y no puedo modificar el código que produce esta fórmula (básicamente una caja negra;)), ya que ves que muchas paréntesis son inútiles.Sin mencionar el hecho de que:

((a) * (b)) + (c) = a * b + c

Entonces quiero mantener el orden de las operaciones Paréntesis, Multiplicar/Dividir, Sumar/Restar.

Estoy trabajando en VB, pero la solución en cualquier idioma estará bien.

Editar

Encontré un problema opuesto (agregue paréntesis a una expresión) Pregunta.

Realmente pensé que esto podría lograrse sin un análisis intenso.Pero parece que es inevitable algún analizador que revise la expresión y la guarde en un árbol de expresiones.

¿Fue útil?

Solución

Podrías eliminar los casos más simples:

([V].[6432]) and (([V].[6443]))

se convierte

v.[6432]

No debería necesitar el [] alrededor del nombre de la tabla o su alias.

Podrías acortarlo aún más si le asignas un alias a las columnas:

select v.[6432] as a, v.[6443] as b, ....

O incluso poner todas las tablas que se consultan en una sola subconsulta; entonces no necesitaría el prefijo de la tabla:

if((-if(a=0;0;(a-b)*((c/1000*d
+c*e+f)*(1-g))))=0;h*
(((c/1000*b*d+c*b*
e+b*f))*(1-g));

select [V].[6432] as a, [V].[6445] as b, [V].[6443] as c, [V].[6448] as d, 
    [V].[6449] as e, [V].[6450] as f,[V].[6446] as g, [V].[6428] as h ...

Obviamente, todo esto es un pequeño pseudocódigo, pero debería ayudarte a simplificar la declaración completa.

Otros consejos

Si está interesado en quitar el paréntesis no necesario en su expresión, la solución genérica consiste en analizar el texto y construir el árbol de expresión asociado.

A continuación, a partir de este árbol, se puede encontrar el texto correspondiente sin paréntesis no es necesario, mediante la aplicación de algunas reglas:

  • si el nodo es un "+", no se requieren paréntesis
  • si el nodo es un "*", a continuación, entre paréntesis son necesarios para la izquierda niño (derecha) sólo si el niño izquierdo (derecho) es un signo "+"
  • mismo se aplica para "/"

Sin embargo, si su problema simplemente es hacer frente a estos 255 caracteres, probablemente puede utilizar variables intermedias para almacenar resultados intermedios

T1 = (([V].[6432])-([V].[6445]))*(((([V].[6443]))/1000*([V].[6448])+(([V].[6443]))*([V].[6449])+([V].[6450]))*(1-([V].[6446])))))
T2 = etc...

Sé que este hilo es muy viejo, pero ya que se pueden realizar búsquedas de Google.

Estoy escribiendo un programa TI-83 Plus calculadora que se ocupa de cuestiones similares. En mi caso, estoy tratando de resolver realmente la ecuación para una variable específica en número, pero todavía puede estar relacionada con su problema, aunque yo estoy usando una matriz, por lo que podría ser más fácil para mí para recoger a cabo valores específicos. ..
No es bastante hecho, pero se deshace de la gran mayoría de paréntesis, con (creo), una solución poco elegante.

Lo que hago es buscar a través de la ecuación / función / lo que sea, hacer el seguimiento de cada uno de los paréntesis de apertura "(" hasta que encuentre un paréntesis que cierre ")", momento en el que puedo estar seguro de que no voy a correr en cualquier más profundamente anidados Parenthese.

y = ((3x + (2))) mostraría el (2) primero, y luego el (3x + (2)), y luego el ((3x + 2))).

Lo que hace es, pues, comprueba los valores inmediatamente antes y después de cada uno de los paréntesis. En el caso anterior, se volvería + y). Cada uno de ellos se le asigna un valor numérico. Entre los dos de ellos, se utiliza la más alta. Si no se encuentran los operadores (*, /, +, ^ o -). Me predeterminado a un valor de 0

A continuación escaneo a través del interior de los paréntesis. Yo uso un sistema de numeración similar, aunque en este caso utilizo el valor más bajo encontrado, no el más alto. Me predeterminado a un valor de 5 si no se encuentra nada, como sería en el caso anterior.

La idea es que se puede asignar un número a la importancia de los paréntesis, restando los dos valores. Si usted tiene algo así como un ^ en el exterior de los paréntesis (2 + 3) ^ 5 los paréntesis son potencialmente muy importante, y se les da un valor alto, (en mi programa que utilizo para ^ 5).

Sin embargo es posible que los operadores dentro de los paréntesis, harían que muy poco importante, (2) ^ 5 donde se encontró nada. En ese caso, el interior se le asignaría un valor de 5. Mediante la sustracción de los dos valores, a continuación, puede determinar si o no un conjunto de paréntesis es neccessary simplemente comprobando si el número resultante es mayor que 0. En el caso de (2 3) ^ 5, a ^ daría un valor de 5, y a + daría un valor de 1. El número resultante sería 4, lo que indicaría que los paréntesis son de hecho necesarios. En el caso de (2) ^ 5 que tendría un valor interno de 5 y un valor externo de 5, lo que resulta en un valor final de 0, lo que demuestra que los paréntesis no son importantes, y se pueden quitar.

La desventaja de esto es que, (al menos en la TI-83) de exploración a través de la ecuación de manera muchas veces es ridículamente lento. Pero si la velocidad no es un problema ... No sé si eso va a ayudar en absoluto, podría estar completamente fuera de tema. Espero que tengas todo y funciona sin problemas.

Estoy bastante seguro de que con el fin de determinar qué paréntesis son innecesarios, que Tienes para evaluar las expresiones dentro de ellos. Debido a que puede anidar paréntesis, esto es, es el tipo de problema recursivo que una expresión regular sólo puede abordar de una manera superficial, y lo más probable que los resultados incorrectos. Si ya está evaluando la expresión, tal vez te gustaría para simplificar la fórmula, si es posible. Esto también se pone un poco complicado, y en algunos enfoques que utiliza técnicas que también se observan en el aprendizaje de máquina, como se puede ver en el siguiente documento: http://portal.acm.org/citation.cfm?id=1005298

Si los nombres de las variables no cambian significativamente de 1 consulta al siguiente, usted podría tratar de una serie de replace () comandos. es decir.

X=replace([QryString],"(([V].[6443]))","[V].[6443]")

También, por qué no puede superar los 255 caracteres? Si va a guardar esto como un campo de cadena en una tabla de Access, entonces usted podría intentar poner la mitad de la expresión en el campo 1 y la segunda mitad en otro.

También puede intentar analizar la expresión utilizando antlr, yacc o similar y crear un árbol de análisis sintáctico. Estos árboles suelen optimizar paréntesis de distancia. A continuación, sólo tendría que crear la expresión de vuelta de árbol (sin paréntesis, obviamente).

Te puede llevar más de un par de horas para conseguir este trabajo sin embargo. Pero el análisis de expresión suele ser el primer ejemplo de análisis genérico, por lo que podría ser capaz de tomar una muestra y modificarlo para sus necesidades.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top