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 で作業していますが、どの言語でも問題なく解決できます。

編集

反対の問題を見つけました (式に括弧を追加します)質問.

これは、重い解析なしで達成できると本当に思っていました。しかし、式を調べて式ツリーに保存するパーサーは避けられないようです。

4

6 に答える 6

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

明らかに、これはすべて少し疑似コードですが、ステートメント全体を単純化するのに役立つはずです

于 2009-06-30T12:54:08.610 に答える
1

このスレッドは非常に古いことは知っていますが、Google で検索できるためです。

同様の問題に対処する TI-83 プラス電卓プログラムを作成しています。私の場合、特定の変数の方程式を実際に数で解こうとしていますが、配列を使用していますが、それでも問題に関連している可能性があるため、特定の値を選択する方が簡単かもしれません. ..
完全には完了していませんが、大部分の括弧を (私が思うに) かなりエレガントな解決策で取り除くことができます。

私がしていることは、方程式/関数/何でもスキャンし、閉じ括弧 ")" が見つかるまで各開き括弧 "(" を追跡することです。括弧。

y=((3x + (2))) は、最初に (2) を表示し、次に (3x + (2)) を表示し、次に ((3x + 2))) を表示します。

次に、各括弧の直前と直後の値をチェックします。上記の場合、 + と ) が返されます。これらにはそれぞれ数値が割り当てられます。それらのうち、高い方が使用されます。演算子 (*、/、+、^、または -) が見つからない場合、デフォルトの値は 0 です。

次に、括弧の中をスキャンします。私は同様の番号付けシステムを使用しますが、この場合は最高値ではなく、見つかった最低値を使用します。上記の場合のように、何も見つからない場合はデフォルトの値 5 に設定します。

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

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

これの欠点は、(少なくとも TI-83 では) 方程式を何度もスキャンするのが途方もなく遅いことです。しかし、速度が問題でなければ...それがまったく役立つかどうかはわかりません。私は完全に話題から外れているかもしれません。すべてがうまくいっていることを願っています。

于 2011-04-04T13:53:30.257 に答える
1

式の不要な括弧を削除することに関心がある場合、一般的な解決策は、テキストを解析して関連する式ツリーを構築することです。

次に、このツリーから、いくつかの規則を適用することにより、不要な括弧なしで対応するテキストを見つけることができます。

  • ノードが「+」の場合、括弧は必要ありません
  • ノードが「*」の場合、左 (右) の子が「+」の場合にのみ、左 (右) の子に括弧が必要です。
  • 「/」も同様

しかし、問題がこれらの 255 文字を処理することだけである場合は、おそらく中間変数を使用して中間結果を保存することができます

T1 = (([V].[6432])-([V].[6445]))*(((([V].[6443]))/1000*([V].[6448])+(([V].[6443]))*([V].[6449])+([V].[6450]))*(1-([V].[6446])))))
T2 = etc...
于 2009-06-30T12:53:34.587 に答える
0

ANTLR、yacc などを使用して式を解析し、解析ツリーを作成することもできます。これらのツリーは通常、括弧を最適化します。次に、ツリーから式を作成するだけです(明らかに括弧なしで)。

ただし、これを機能させるには数時間以上かかる場合があります。ただし、式の解析は通常、一般的な解析の最初の例であるため、サンプルを取得して必要に応じて変更できる場合があります。

于 2009-06-30T12:46:53.960 に答える
0

どの括弧が不要かを判断するには、括弧内の式を評価する必要があると確信しています。括弧を入れ子にすることができるため、これは再帰的な問題の一種であり、正規表現では浅い方法でしか対処できず、誤った結果になる可能性が最も高くなります。すでに式を評価している場合は、可能であれば式を単純化したいかもしれません。これもややこしく、一部のアプローチでは機械学習でも見られる手法を使用しています

于 2009-06-30T12:35:59.210 に答える
0

変数名がクエリごとに大きく変わらない場合は、一連の replace() コマンドを試すことができます。すなわち

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

また、なぜ 255 文字を超えることができないのでしょうか。これを文字列フィールドとして Access テーブルに格納している場合は、式の半分を 1 つのフィールドに入れ、残りの半分を別のフィールドに入れることができます。

于 2009-06-30T12:37:43.840 に答える