Pergunta

Oi eu queria saber se há alguma maneira conhecida para se livrar de parênteses desnecessários em fórmula matemática. A razão que eu estou fazendo esta pergunta é que eu tenho para minimizar tais comprimento 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])));

é basicamente parte da instrução SQL select. Ele não pode ultrapassar 255 caracteres e que não pode modificar o código que produz esta fórmula (basicamente uma caixa preta;)) Como você vê muitos parênteses são inúteis. Sem mencionar o fato de que:

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

Então eu quero manter a ordem das operações Parêntese, Multiplicar / Dividir, Adicionar / Subtrair.

Im trabalhando em VB, mas solução em qualquer idioma vai ficar bem.

Editar

Eu encontrei um problema oposto (parênteses Adicionar a uma expressão) Pergunta .

Eu realmente pensei que isso poderia ser realizado sem análise pesado. Mas parece que alguns analisador que irá percorrer a expressão e salve-o em uma árvore de expressão é unevitable.

Foi útil?

Solução

Você poderia tirar os casos mais simples:

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

Torna-se

v.[6432]

Você não deve precisar o [] ao redor do nome da tabela ou seu alias.

Você pode encurtar o mais se você pode apelidar as colunas:

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

Ou até mesmo colocar todas as tabelas sendo consultadas em um único subconsulta - então você não precisa o prefixo da tabela:

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, isso é tudo psedo-código um pouco, mas deve ajudar a simplificar a declaração completa

Outras dicas

Se você está interessado em remover o parêntese não necessário em sua expressão, a solução genérica consiste em analisar seu texto e construir a árvore de expressão associada.

Então, a partir desta árvore, você pode encontrar o texto correspondente sem parêntese não necessário, através da aplicação de algumas regras:

  • Se o nó é um "+", nenhum parêntese são obrigados
  • Se o nó é um "*", então parênteses são necessários para (direita) criança entregue apenas se o (direita) filho esquerdo é um "+"
  • o mesmo se aplica para "/"

Mas se o seu problema é apenas para lidar com esses 255 caracteres, você provavelmente só pode usar variáveis ??intermediárias para armazenar resultados intermediários

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

Eu sei que esta discussão é muito velho, mas como é pesquisável do Google.

Eu estou escrevendo um programa TI-83 Plus calculadora que aborda questões semelhantes. No meu caso, eu estou tentando realmente resolver a equação para uma variável específica em número, mas ele ainda pode se relacionar com o seu problema, embora eu estou usando uma matriz, por isso pode ser mais fácil para mim para escolher valores específicos. ..
Não é bem feito, mas não se livrar da grande maioria dos parênteses com (eu acho), uma solução pouco elegante.

O que faço é varredura através da equação / função / whatever, mantendo o controle de cada parenthese abertura "(" até que eu encontre um parenthese fechamento ")", em que ponto eu posso ter certeza que eu não vou correr em qualquer mais profundamente parenthese aninhada.

y = ((3x + (2))) iria mostrar o (2) em primeiro lugar, e, em seguida, o (3x + (2)), e, em seguida, o ((3x + 2))).

O que ele faz é, então, verifica os valores imediatamente antes e depois de cada parenthese. No caso acima, ele voltaria + e). Cada um deles é atribuído um valor numérico. Entre os dois, maior é usado. Se há operadores são encontrados (*, /, +, ^, ou -). I padrão para um valor de 0

Em seguida eu percorrer o interior dos parênteses. Eu uso um sistema de numeração semelhante, embora, neste caso, eu uso o menor valor encontrado, não o maior. Eu padrão para um valor de 5, se nada for encontrado, como seria no caso acima.

A idéia é que você pode atribuir um número a importância dos parênteses subtraindo os dois valores. Se você tiver algo como um ^ do lado de fora dos parênteses (2 + 3) ^ 5 esses parênteses são potencialmente muito importante, e seria dado um valor alto, (no meu programa eu uso para 5 ^).

É possível, porém, que os operadores dentro tornaria os parênteses muito importante, (2) ^ 5 onde nada é encontrado. Nesse caso, o interior seria atribuído um valor de 5. Subtraindo os dois valores, então você pode determinar se ou não um conjunto de parênteses é neccessary simplesmente, verificando se o número resultante for superior a 0. No caso de (2 3) 5 ^, a ^ daria um valor de 5, e a + iria dar um valor de 1. O número resultante seria 4, o que indicaria que os parênteses são de facto necessária. No caso de (2) ^ 5, você teria um valor intrínseco de 5 e um valor externo de 5, resultando em um valor final de 0, mostrando que os parênteses não são importantes, e pode ser removido.

A desvantagem para isso é que, (pelo menos na TI-83) digitalização através da equação tantas vezes é ridiculamente lento. Mas se a velocidade não é um problema ... Não sei se isso vai ajudar em nada, eu poderia ser completamente fora do tópico. Espero que você tem tudo instalado e funcionando.

Eu tenho certeza de que, a fim de determinar o que parênteses são desnecessários, você Have para avaliar as expressões dentro deles. Porque você pode parênteses ninho, este é o tipo de problema recursivo que uma expressão regular pode somente endereço de uma forma superficial, e provavelmente a resultados incorretos. Se você já está avaliando a expressão, talvez você gostaria de simplificar a fórmula, se possível. Isto também fica meio complicado, e em algumas abordagens técnicas usa esse que também são vistos no aprendizado de máquina, como você pode ver na seguinte papel: http://portal.acm.org/citation.cfm?id=1005298

Se os seus nomes de variáveis ??não mudam significativamente a partir de 1 de consulta para o próximo, você pode tentar uma série de substituir comandos (). i.

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

Além disso, por que não pode ultrapassar 255 caracteres? Se você estiver armazenando isso como um campo de cadeia em uma tabela do Access, então você pode tentar colocar metade da expressão em um campo e a segunda metade em outra.

Você também pode tentar analisar sua expressão usando ANTLR, yacc ou similar e criar uma árvore de análise. Estas árvores geralmente otimizar parênteses distância. Então você só tem que criar a expressão de volta da árvore (sem parênteses obviamente).

Pode levar mais do que algumas horas para começar este trabalho embora. Mas a expressão de análise é geralmente o primeiro exemplo em análise genérica, de modo que você pode ser capaz de tomar uma amostra e modificá-lo para suas necessidades.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top