2009-06-30 31 views
4

嗨,我想知道是否有任何已知的方法來擺脫數學公式中不必要的括號。我問這個問題的原因是我必須儘量減少這種公式長度如何擺脫數學表達式中不必要的括號

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工作,但任何語言的解決方案將罰款。

編輯

我發現了一個相反的問題(加括號的表達式)Question

我真的認爲這可以在沒有大量解析的情況下完成。但似乎有些解析器會通過表達式並將其保存在表達式樹中,這是不可避免的。

回答

2

你可以剝奪最簡單的情況:

([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代碼,但它應該幫助您簡化了聲明全文

+0

謝謝基思。我會放棄它。 – Pawel 2009-06-30 13:01:53

0

我敢肯定,爲了確定什麼括號是不必要的,你來評估它們中的表達式。因爲你可以嵌套圓括號,所以這是一種遞歸問題,正則表達式只能以淺的方式解決,並且最可能導致錯誤的結果。如果您已經在評估表達式,也許您想盡可能簡化公式。這也有點棘手,並且在某些方法中使用了也可以在機器學習中看到的技術,例如您可能在以下論文中看到的:http://portal.acm.org/citation.cfm?id=1005298

0

如果您的變量名稱從1查詢沒有顯着變化爲接下來,您可以嘗試一系列replace()命令。即

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

另外,它爲什麼不能超過255個字符?如果您將它作爲字符串字段存儲在Access表中,則可以嘗試將表達式的一半放在1字段中,將後半部分放在另一個字段中。

0

你也可以嘗試使用ANTLR,yacc或類似語法解析你的表達式並創建一個分析樹。這些樹通常優化括號。那麼你只需要從樹中創建表達式(顯然沒有括號)。

雖然這可能需要幾個小時才能完成。但是表達式解析通常是泛型解析的第一個例子,所以您可能能夠取樣並根據需要對其進行修改。

1

如果您有興趣去除表達式中的非必要括號,通用解決方案包括解析文本並構建關聯的表達式樹。

然後,從這個樹,你可以通過應用一些規則,發現沒有非必要的括號內的相應文本,:

  • 如果節點是一個「+」,不需要括號
  • 如果節點是「*」,然後括號所必需的左(右)子只在左(右)孩子是個「+」
  • 同樣適用於「/」

但是如果你的問題只是爲了處理這些問題255個字符,你可能只用中間變量保存中間結果

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

我知道這個線程是真的老了,但因爲它是從搜索 谷歌。

我正在寫一個TI-83 plus計算器程序來解決類似的問題。在我的情況下,我試圖實際解決數字中特定變量的等式,但它仍然可能與您的問題有關,儘管我使用的是數組,所以我可能更容易挑選出特定的值。 ..
這並沒有完成,但它確實擺脫了絕大多數括號(我認爲),這是一個有點優雅的解決方案。

我所做的是掃描公式/函數/任何,跟蹤每個開放圓括號「(」直到我找到一個閉合圓括號「),在這一點上,我可以放心,我不會碰到任何更深嵌套的括號。 y =((3x +(2)))將首先顯示(2),然後顯示(3x +(2)),然後顯示((3x + 2)))。

它然後在每個括號之前和之後檢查值。在上面的情況下,它會返回+和)。每個這些都被分配一個數字值。在他們兩個之間,使用更高的。如果找不到運算符(*,/,+,^或 - ),則默認值爲0.

接下來我掃描圓括號的內部。我使用類似的編號系統,但在這種情況下,我使用的是最低值,而不是最高值。如果沒有發現任何東西,我默認值爲5,就像上面的情況一樣。

想法是,您可以通過減去兩個值來爲括號的重要性分配數字。如果你在括號外面有一個^,那麼這些括號可能非常重要,並且會被賦予一個很高的值(在我的程序中我使用5來表示^)。

然而,內部操作員可能會使括號非常不重要,因爲沒有找到任何內容。在這種情況下,內部將被分配一個值5.通過減去這兩個值,然後您可以簡單地通過檢查結果數是否大於0來確定是否需要一組括號。在(2 +3)^ 5,a ^會給出5的值,並且a +會給出1的值。結果數字將爲4,這表明實際上需要括號。 對於(2)^ 5,您的內部值爲5,外部值爲5,結果 的最終值爲0,表明括號不重要,可以刪除。

這樣做的缺點是(至少在TI-83上)多次掃描方程的速度是非常慢的。但是,如果速度不是問題... 不知道這是否會有所幫助,我可能完全脫離主題。希望你把所有的東西都搞好了,工作。