题
您好,我想知道是否有任何已知的方法可以消除数学公式中不必要的括号。我问这个问题的原因是我必须最小化这样的公式长度
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])));
它基本上是 sql select 语句的一部分。它无法超越255个字符,我无法修改产生此公式的代码(基本上是黑匣子;)),因为您看到许多括号没有用。更不用说以下事实:
((a) * (b)) + (c) = a * b + c
所以我想保持括号、乘/除、加/减的运算顺序。
我用 VB 工作,但任何语言的解决方案都可以。
编辑
我发现了一个相反的问题(在表达式中添加括号) 问题.
我真的认为这可以在不进行大量解析的情况下完成。但似乎某些解析器将遍历表达式并将其保存在表达式树中是不可避免的。
解决方案
您可以剥去最简单的情况:
([V].[6432]) and (([V].[6443]))
变为
v.[6432]
您应该不需要的[]围绕表名称或其别名。
您可以进一步缩短,如果你可以别名的列:
select v.[6432] as a, v.[6443] as b, ....
甚至把所有的表被查询到单个子查询 - 那么你就不需要表前缀:
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 ...
显然,这一切都有点psedo代码,但它应该帮助您简化了声明全文
其他提示
如果您有兴趣删除表达式中不必要的括号,通用解决方案包括解析文本并构建关联的表达式树。
然后,从这棵树中,您可以通过应用一些规则找到相应的文本,而无需不必要的括号:
- 如果节点是“+”,则不需要括号
- 如果节点是“*”,则仅当左(右)子节点是“+”时,左(右)子节点才需要括号
- 同样适用于“/”
但如果你的问题只是处理这 255 个字符,你可能可以只使用中间变量来存储中间结果
T1 = (([V].[6432])-([V].[6445]))*(((([V].[6443]))/1000*([V].[6448])+(([V].[6443]))*([V].[6449])+([V].[6450]))*(1-([V].[6446])))))
T2 = etc...
我知道这个线程是真的老了,但因为它是从谷歌搜索。
我正在写一个TI-83 +计算器程序,解决类似的问题。在我的情况,我想真正解决方程在数一个特定的变量,但它仍可能涉及到您的问题,虽然我使用一个数组,所以它可能是更容易为我挑选出具体数值。 ..结果 它没有完全完成,但它确实摆脱了绝大多数括号与(我认为),有点优雅的解决方案。
的我做的是通过扫描式/功能/不管,跟踪每个开口parenthese的“(”,直到找到一个闭合parenthese“)”,在这一点上,我可以放心,我不会碰到任何更深度嵌套parenthese。
Y =((3×+(2)))会表现出(2)第一,然后(3×+(2)),然后将((3×+ 2)))。
它的作用是接着相邻的两个parenthese后检查的值。在上述情况下,它会返回+和)。每个这些被分配一个数字值。他们两个之间,则使用更高。如果没有找到运算符(*,/,+,^,或 - )。我默认为值0
接下来,我通过括号内进行扫描。我使用了类似的编号系统,尽管在这种情况下,我使用发现,不是最高的最低值。我默认值5,如果没有找到,如将在上述情况中。
的想法是,可以通过减去这两个值分配一个编号以括号中的重要性。如果你碰到这样的一对括号外面^ (2 + 3)^ 5 这些括号是潜在的非常重要的,将被给予很高的价值,(在我的节目,我用5 ^)。
有可能的但是使内运营商将使得括号非常不重要, (2)^ 5 在那里没有发现。在这种情况下的内部将被分配的值5通过减去这两个值,就可以判断一组括号是否是简单地neccessary通过检查所得到的数量是否大于0。在的情况下更大的(2 3)^ 5,^将给予5的值,并且a +将给出值1。将所得的数目将是4,这将表明在实际上所需要的括号。 在的情况下,(2)^ 5你将有5内值和5的外值,所得的 在0的最终值,表明括号是不重要的,并且可以被移除。
这样做的缺点是,(至少在TI-83)通过方程扫描这么多次是可笑缓慢。但是,如果速度不是问题... 不知道这是否会在所有帮助,我可能完全偏离主题。希望你有一切行动和工作。
我敢肯定的是,为了确定哪些括号是不必要的,你的的的内他们评估的表达式。因为你可以嵌套括号,这是哪门子的递归问题的一个正则表达式可以在浅方式只能解决,而最有可能不正确的结果。如果你已经在评估表达,也许你想,如果能够简化公式。这也得到一定的技巧,而且在某些方式使用技术,这也可见于机器学习,比如你可以在下面的纸张看到:的 http://portal.acm.org/citation.cfm?id=1005298
如果您的变量名不要在1个查询显著更改为下一个,你可以尝试一系列取代的()命令。即。
X=replace([QryString],"(([V].[6443]))","[V].[6443]")
此外,为什么不能超过255个字符?如果要存储此作为一个字符串字段中Access表,则可以尝试把一半的表达在1场和第二半中的另一
您也可以尝试使用解析ANTLR,YACC或类似的表达,并创建一个解析树。这些树通常优化括号之遥。然后,你就只需要创建表达式从一棵树后面(没有括号明显)。
这可能需要你多几个小时,虽然得到这个工作。但表达分析通常是在通用解析第一个例子,所以你也许可以采取抽样并修改它以您的需求。