以下のような表現があります。
{1000} AND ({1001} OR {1002} OR {1003})
許可される演算子は OR と AND で、括弧を使用して式をネストできます。PHP 5.3 で実装された Shunting Yard アルゴリズムを使用して、この文字列をトークン化し、抽象構文木 (AST) に変換することができました。上記の式の結果は次のようになります。
1000 1001 1002 | 1003 | &
&
/ \
1000 |
/ \
| 1003
/ \
1001 1002
このツリーをトラバースするとき、ユーザーが選択できる数値の最終的な組み合わせを出力したいと考えています。与えられた表現では、これは不可能です。私が必要とするのは、実際には分配法則が適用された後のフォームです。
(1000 & 1001) | (1000 & 1002) | (1000 & 1003)
1000 1001 & 1000 1002 & | 1000 1003 & |
_______________|_____________
/ \
_______|____ &
/ \ / \
& & 1000 1003
/ \ / \
1000 1001 1000 1002
&-operator ノードとして許可されているノードは、リーフを運ぶ最後のノードだけであると結論付けました。他のすべては |-operator ノードでなければなりません。
上記で説明した文法を使用して任意の AST を、すべての最終順列を表すものに変換する方法は? 中置表現のトークンに分配法則を適用する方がよいでしょうか? ツリーの代わりに RPN 表現を使用する方が簡単ですか?
また、次のようなより難しい例があることにも注意してください。
(1000 & 1008) & (1001 | 1002 | 1003)
1000 1008 & 1001 1002 | 1003 | &
______ & ___
/ \
& |
/ \ / \
1000 1008 | 1003
/ \
1001 1002
結果として欲しいのは:
(1000 & 1008 & 1001) | (1000 & 1008 & 1002) | (1000 & 1008 & 1003)
1000 1008 & 1001 & 1000 1008 & 1002 & | 1000 1008 & 1003 & |
__________________|_________
/ \
_____________|_________ &
/ \ / \
& & & 1003
/ \ / \ / \
& 1001 & 1002 1000 1008
/ \ / \
1000 1008 1000 1008
別の (より複雑な) 例として、左側のサブツリーと右側のサブツリーを切り替えるか、別の &-node を 1003 => 1003 1009 & の代わりに追加します。
私がすでに試したこと: 何度もグーグル検索し、ツリーの前後の順序をトラバースし、成功しなかったアルゴリズムを見つけようとしました。
正しい方向へのヒントや指針に感謝します。