これは、私がかつて作成した、変更されたプレフィックス ツリー/トライを思い出させます。少し違いますが、うまくいくかもしれません。境界が大きい/境界がない場合、またはそれを自分の言語に変換できない場合 (私は c++ でコーディングしています)、機能しない可能性があります。
つまり、基本的にはトライでは次の文字に対応する子を格納するのが普通ですが、私は各文字の頻度に対応する子を格納しました。
基本的に(私の観点から)質問は、「サブセットと同じかそれ以上の文字を持つセットはありますか?」です。たとえば、サブセットが { A,D,E,E } の場合、少なくとも 1 つの A、1 つの D、および 2 つの E を含むセットがあるかどうかを確認する必要があります。
だから、トライのためにあなたはこのようなものを持っています
Root
/ | \
/ /|\ \
/ / | \ \
1 2 ... MAX <-- This represents the frequency of "A"
/|\ ..... /|\
1..MAX 1..MAX <-- Frequency of "B"
...............
...............
...............
1 ... ... ... MAX <-- Frequency of "Y"
/|\ .... .... / | \
1..MAX ...... 1 .. MAX <-- Frequency of "Z"
基本的にすべての ... は、表示に時間がかかりすぎる多くのものを表しています。/,| と \ は親子関係を表し、MAX は文字の最大頻度を表します。
つまり、次のような構造体 (私は C++ でコーディング) があります。
struct NODE {
NODE *child[MAX + 1]; // Pointers to other NODE's that represents
// the frequency of the next letter
};
ノードを作成するときは、そのすべての子を NULL に初期化する必要があります。これは、コンストラクター (C++ の場合) または makeNode() 関数を使用して行うことができます。
NODE* makeNode() {
NODE* n = new NODE; // Create a NODE
for(int i = 0;i <= MAX;i++) // For each child
n->child[i] = NULL; // Initialize to NULL
};
最初は、トライは単なるルートです
NODE* root = new NODE;
トライにセットを追加すると、各文字の頻度が取得され、トライが実行されます。特定のノードで、次の文字に対応する子が NULL の場合、新しい NODE を作成するだけです。
トライを検索するときは、サブセット内の文字の頻度以上に対応する各ノードのすべての子を検索します。たとえば、サブセットに 3 つの A がある場合、root->child[3]、次に root->child[4]、次に ... root->child[MAX] のすべてを検索します。
それはおそらく非常に複雑で紛らわしいので、1) 私が怒っていないと思うなら、何が紛らわしいのかについてコメントしてください.