Question

Salut, je me demandais s'il y a un moyen connu pour se débarrasser des parenthèses inutiles dans la formule mathématique. La raison pour laquelle je pose cette question est que je dois minimiser une telle longueur de formule

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])));

il est essentiellement une partie de l'instruction select SQL. Il ne peut pas dépasser 255 caractères et I ne peut pas modifier le code qui produit cette formule (essentiellement une boîte noire;)) Comme vous le voyez beaucoup de parenthèses sont inutiles. Sans parler du fait que:

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

Je veux garder l'ordre des opérations Parenthèses, Multiplier / Diviser, Ajouter / Soustraire.

Im travaille en VB, mais la solution dans toutes les langues ira bien.

Modifier

J'ai trouvé un problème inverse (ajouter entre parenthèses à une expression) Question .

Je pensais vraiment que cela pourrait se faire sans analyse syntaxique lourde. Mais il semble que certains analyseur qui passera par l'expression et l'enregistrer dans un arbre d'expression est unevitable.

Était-ce utile?

La solution

Vous pouvez dépouiller les cas les plus simples:

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

Devient

v.[6432]

Vous ne devriez pas avoir le [] autour du nom de la table ou son alias.

Vous pouvez raccourcir davantage si vous pouvez créer un alias pour les colonnes:

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

Ou même mis toutes les tables interrogées en une seule sous-requête - vous donc pas besoin du préfixe de table:

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 ...

Il est évident que tout cela est un psedo code binaire, mais il devrait vous aider à simplifier la déclaration complète

Autres conseils

Si vous êtes intéressé à supprimer la parenthèse non nécessaire dans votre expression, la solution générique consiste à l'analyse de votre texte et construire l'arbre d'expression associée.

Ensuite, à partir de cet arbre, vous pouvez trouver le texte correspondant sans parenthèses non nécessaire, en appliquant certaines règles:

  • si le nœud est un « + », pas entre parenthèses sont nécessaires
  • si le nœud est un « * », puis entre parenthèses sont nécessaires pour les enfants de gauche (à droite) que si l'enfant gauche (à droite) est un « + »
  • même pour appliquer "/"

Mais si votre problème est juste pour traiter ces 255 caractères, vous pouvez probablement utiliser des variables intermédiaires pour stocker les résultats intermédiaires

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

Je sais que ce fil est vraiment vieux, mais comme il est consultable à partir de Google.

J'écris un programme calculatrice TI-83 qui traite des questions similaires. Dans mon cas, je suis en train de réellement résoudre l'équation à une variable particulière en nombre, mais il peut encore se rapporter à votre problème, bien que j'utilise un tableau, donc il peut être plus facile pour moi de choisir des valeurs spécifiques. ..
Il est pas tout à fait terminé, mais il ne se débarrasser de la grande majorité des parenthèses avec (je crois), une solution peu élégante.

Ce que je fais est de scanner par l'équation / fonction / whatever, garder une trace de chaque ouverture Parenthese « ( » jusqu'à ce que je trouve une parenthèse fermante « ) », à quel point je peux être assuré que je ne courrai pas dans une plus Parenthese profondément imbriquées.

y = ((3x + (2))) montrerait le (2) d'abord, puis le (3x + (2)), puis le ((3x + 2))).

Ce qu'il fait est vérifie ensuite les valeurs immédiatement avant et après chaque parenthese. Dans le cas ci-dessus, il retournerait + et). Chacun d'entre eux est attribué une valeur numérique. Entre les deux d'entre eux, plus est utilisé. Si aucun opérateur se trouvent (*, /, +, ^, ou -). I par défaut à une valeur de 0

Ensuite, je scan par l'intérieur des parenthèses. J'utilise un système de numérotation similaire, bien que dans ce cas, j'utilise la valeur la plus basse trouvée, pas le plus élevé. Je défaut à une valeur de 5 si rien ne se trouve, comme le serait dans le cas ci-dessus.

L'idée est que vous pouvez attribuer un numéro à l'importance des parenthèses en soustrayant les deux valeurs. Si vous avez quelque chose comme un ^ à l'extérieur des parenthèses (2 + 3) ^ 5 ces parenthèses sont potentiellement très importants et seraient donnés une valeur élevée, (dans mon programme que j'utilise 5 pour ^).

Il est cependant possible que les opérateurs à l'intérieur rendrait les parenthèses très peu d'importance, (2) ^ 5 où rien ne se trouve. Dans ce cas, l'intérieur serait attribué une valeur de 5. En soustrayant les deux valeurs, vous pouvez déterminer si oui ou non un ensemble de parenthèses neccessaire simplement en vérifiant si le nombre obtenu est supérieur à 0. Dans le cas de (2 3) ^ 5, a ^ donnerait une valeur de 5, et a + donnerait une valeur de 1. Le nombre résultant serait de 4, ce qui indiquerait que les parenthèses sont en fait nécessaires. Dans le cas de (2) ^ 5 vous auriez une valeur intérieure de 5 et une valeur externe de 5, ce qui à une valeur finale de 0, ce qui montre que les parenthèses ne sont pas importantes, et peuvent être supprimés.

L'inconvénient de ceci est que, (au moins sur la TI-83) à balayage à travers l'équation tant de fois est ridiculement lent. Mais si la vitesse est pas un problème ... Je ne sais pas si cela aidera tout, je pourrais être complètement hors sujet. Nous espérons que vous avez tout et de travail.

Je suis assez sûr que pour déterminer les parenthèses ne sont pas nécessaires, vous Vous pour évaluer les expressions en leur sein. Parce que vous pouvez parenthèses imbriquer, c'est le genre de problème récursif qu'une expression régulière ne peut traiter de manière peu profonde, et très probablement à des résultats incorrects. Si vous évaluez déjà l'expression, peut-être que vous souhaitez simplifier la formule si possible. Cela devient aussi un peu délicat, et certaines approches utilise des techniques que ce sont également visibles dans l'apprentissage de la machine, comme vous pouvez le voir dans le document suivant: http://portal.acm.org/citation.cfm?id=1005298

Si vos noms de variables ne changent pas significativement de 1 requête à l'autre, vous pouvez essayer de remplacer une série () commandes. i.e..

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

En outre, pourquoi ne peut-il dépasser 255 caractères? Si vous stockez cela comme un champ de chaîne dans une table d'accès, vous pouvez alors essayer de mettre la moitié de l'expression dans 1 champ et la seconde moitié dans une autre.

Vous pouvez également essayer votre expression en utilisant l'analyse syntaxique ANTLR, yacc ou similaires et de créer un arbre d'analyse syntaxique. Ces arbres optimisent habituellement entre parenthèses loin. Ensuite, vous devez juste créer l'expression de retour de l'arbre (sans parenthèses évidemment).

Il pourrait vous prendre plus de quelques heures pour obtenir ce travail cependant. Mais l'analyse syntaxique d'expression est généralement le premier exemple sur l'analyse syntaxique générique, donc vous pourriez être en mesure de prendre un échantillon et le modifier selon vos besoins.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top