web-dev-qa-db-ja.com

リストを論理ANDおよびORで連結する方法

整数の複数のリストを持っている、例えば:

_var p1 = new[] { 3, 9, 5, 8, 9 };
var p2 = new[] { 12, 1, 18, 27, 103, 99, 4 };
var p3 = new[] { 23, 930, 15 };
// ...
_

これらを論理ANDおよびOR演算と連結したいとします。例:

_var result = p1 AND p2 OR p3 ...
_

ANDORよりも優先される必要があります。 resultもリストです。

定義:

  • _a OR b_は、リストaまたはbのいずれかに存在する整数を使用して、リストを生成する必要があります。
  • _a AND b_は、リストabの両方に存在する整数のみを取って、リストを生成する必要があります。

これを解決するのが複雑になるのは、リストの数(およびその内容)が実行時にユーザーによって定義されることと、リストを連結する方法の演算子です。

つまりユーザーは5つのリストを定義して_p1 OR p2 AND p3 AND p4 OR p5_のように連結するか、2つのリストを定義して_p1 AND p2_のように連結することができます。または、20個のリストを定義して、それらをANDORの任意の組み合わせで連結することもできます。

解決策の試み

私の最初のアプローチは、いくつかのC#式パーサーを取得し、独自の演算子(ANDORなど)を導入するか、少なくとも_*_をANDおよび_+_ as OR)。

残念ながら見つかりませんでした。私が遭遇した最も近いものは Florian Rapplによる魔道士 で、演算子のオーバーロードをサポートしていないようです。

今、私はアイデアがありません。自分で文法を定義し、レクサーやその他の複雑なもの(私にとって)を書く必要があるのではないかと恐れています。

私の質問

これを解決する方法についてのアイデアを探しています。多分私の公式のパーサーのアイデア以外にも完全に他の方法があるでしょう。

1
Uwe Keim

探している操作は、例のAND/ORと同等の操作である交差と結合です。任意の操作で任意のセットを処理する必要がある場合は、基本的に独自のパーサーを構築する必要があります。処理できるものへの入力を取得することが最初のステップです。整数のリストのリストと実行する操作のリストは、おそらくデータを保持するための最も簡単なセットアップです。マッピングORを結合してANDを交差させることはそれほど難しくありません。2番目のステップは、正しい順序の操作を構築することです。最初のリストと操作から始めます。 2番目のリストが他の2つのリストの積であるか、次に提供されるリストであるかを判断するために、次の演算を先読みする必要があります。演算がなくなるまでこれを行うと、結果の式は評価時に正しいリストを提供します。

たとえば、_p1 OR p2 AND p3 AND p4 OR p5_は、解析後に次のようになりますp1.union(p2.intersect(p3).intersect(p4)).union(p5)

3
Ryathal

パーサーが必要になる唯一の理由は、ユーザーに次のようなものを入力させる場合です。

3, 9, 5, 8, 9 AND 12, 1, 18, 27, 103, 99, 4

ユーザーが次のように入力している場合:

p1 + p2 * p3 * p4 + p5 

次に、ライブラリを作成し、ユーザーはプログラマーです。 C#はパーサーです。

この場合は operator overloading が必要です。

どちらの場合も、C#を使用しているので、 Hashset を見てください。それはあなたのために行われたユニオンと交差のすべてのロジックを持っています。それはあなたのクラスを支えるための良いコレクションでしょう。

2
candied_orange