2009-06-30 16 views
4

こんにちは私は、数式で不必要なカッコを取り除くための既知の方法があるかどうか疑問に思っていました。私はこの質問をしていた理由は、私はそれが基本的にSQLのSELECT文の一部である、このような式長数式で不必要なカッコを取り除く方法

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

を最小限にしなければならないということです。 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

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

    を簡素化すべきであるが、それはから検索可能であるとしてgoogle。

    私は同様の問題に対処するTI-83プラス電卓プログラムを作成しています。私の場合、実際には数値の特定の変数の方程式を解くことを試みていますが、配列を使用していますが、それでも問題に関連している可能性がありますので、特定の値を選ぶ方が簡単かもしれません。 ..
    これはあまり行われていませんが、(私は思うが)やや優雅な解決策の大半を取り除いています。

    私がしているのは、式/関数/何でもスキャンして、それぞれの冒頭括弧を追跡しています。 "(私は閉鎖括弧が見つかるまで") "その時点で私は逃げないと確信できますより深く入れ子にされた親の括り。 (3x + 2))は、(2x)、次いで(3x + 2)、次いで((3x + 2))を示す。

    次に、各親カテゴリの直前と直後の値をチェックします。上記の場合、+と)を返します。これらのそれぞれには数値が割り当てられます。それらの2つの間で、より高いものが使用される。演算子が見つからない場合(*、/、+、^、 - )、デフォルト値は0になります。

    次に、かっこ内をスキャンします。私は同様のナンバリングシステムを使用していますが、この場合は最高値ではなく、最低値を使用します。上記の場合と同様に、何も見つからない場合はデフォルトで5になります。

    2つの値を減算することによって、カッコの重要度に数値を割り当てることができます。 (2 + 3)^ 5 括弧の外側に^のようなものがある場合、それらの括弧は潜在的に非常に重要であり、高い価値が与えられます(私のプログラムでは^を5とします)。

    しかし、内側の演算子は、かっこを非常に重要でないものにする可能性があります。(2)^ 5 ここで何も見つかりません。その場合、内部に5の値が割り当てられます.2つの値を減算することによって、結果の数値が0より大きいかどうかを確認するだけで、かっこのセットが必要かどうかを判断できます。(2 +3)^ 5、a ^は5の値を与え、a +は1の値を与えます。結果の数は4であり、かっこが実際に必要であることを示します。 (2)^ 5の場合、内側の値が5、外側の値が5で、結果として が最終値0になり、かっこが重要でなく、削除できることが示されます。

    これの欠点は、(少なくともTI-83では)方程式を何度もスキャンすることが非常に遅いことです。しかし、スピードが問題ではない場合... それはまったく助けになるかどうかわからない、私は完全に話題かもしれない。あなたはすべてが稼働していることを願っています。

    関連する問題