これらの文字列操作をサポートする「文字列スタック」データ構造はありますか?


28

次の操作を実行できる文字セット文字列セットを格納するデータ構造を探しています。文字列のセットSを格納するデータ構造としてDS を示します。ΣD(S)S

  • Add-Prefix-Set上に:いくつかのセットの所定のT大き定数によって制限され、その文字列の長さが一定で、戻りによって囲まれている文字列(空)の、D{ T Sを| T T S S } 。これらの境界定数は両方ともグローバルです。これらはすべての入力Tで同じです。D(S)TD({ts | tT,sS})T
  • Get-Prefixes上の:リターン{ | S S Σ }O | Σ |時間でその内容を列挙できる限り、このセットにどの構造が使用されるかはあまり気にしないことに注意してください。D(S){a | asS,aΣ}O(|Σ|)
  • Remove-Prefixes上の:リターンD{ S | A S S Σ } D(S)D({s | asS,aΣ})
  • Merge:指定されたおよびDT 、リターンDS T D(S)D(T)D(ST)

今、私は本当にこれらのすべての操作を時間で実行したいのですが、これらのすべての操作をo n 時間で実行する構造で問題ありません。ここで、nはの最も長い文字列の長さです構造。マージの場合、私はたいO N 1 + N 2実行時、nは1であり、nは第ためのN 2 N第2の構造のために。O(1)o(n)no(n1+n2)n1nn2n

追加の要件は、構造が不変であること、または少なくとも上記の操作が「新しい」構造を返し、古い構造へのポインタが以前と同様に機能することです。

償却に関するメモ:それは問題ありませんが、永続性に注意する必要があります。古い構造を常に再利用するため、同じ構造に対して特定の操作セットで最悪のケースにぶつかると、問題が発生します(そのため、作成される新しい構造は無視されます)。

私が取り組んでいる解析アルゴリズムでこのような構造を使用したいと思います。上記の構造は、アルゴリズムに必要な先読みを保持します。

私はすでにトライの使用を検討していますが、主な問題は、試行を効率的にマージする方法がわからないことです。の文字列セットが1文字の文字列Add-Prefix-Setのみで構成される場合、これらのセットをスタックに格納できます。これにより、最初の3つの操作の実行時間がます。ただし、このアプローチはマージにも機能しません。O(1)

最後に、私は要因に興味がないことに注意してください:これは私が気にすることすべてについて一定です。|Σ|


文字列は操作によってのみ構築されAdd-Prefix-Setますか、それとも文字列の任意のセットから始めますか?
ジョー

2
n1=n2STo(n1+n2)

(ちょうどあなたがすることができますが、その中に1つの単一文字列とセットで開始しますが、空の文字列も同様に細かいAdd-Prefix-Setことで)
アレックス10ブリンク

@Joe:良い質問です-私は、マージ操作はかなり休憩に、このような構造を得ることのチャンスを確信して取得し始めています...
アレックス10ブリンク

(n1,n2)

回答:


5

私はかなり長い間考えていましたが、トライのようなDAG構造で可能な限り最も愚かな方法ですべての操作を行うことに問題は見つかりませんでした:

Add-Prefix-Set

T

O(|T|)

マージ

2つの構造のルートを結合します。最初のノードの2番目のルートのすべての子ノードを子にします。これで、同じノードからの同じ文字でマークされた複数のエッジを持つことができます。

O(1)

ルートの遅延更新

  1. O(|Σ|)O(1)
  2. O(1)

プレフィックスの取得

ルートを遅延更新します。次に、ルートのすべての子を見つけ、それらに向かうエッジ上の文字のセットを報告します。

O(|Σ|)

プレフィックスの削除

ルートを遅延更新します。ルートのすべての子を結合し、ルートポインタをこの結合の結果に設定します。新しいルートを遅延更新します。

O(|Σ|)

持続性

O(1)O(|Σ|)O(logN)N

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.