2008-08-30 11 views
2

は、例として次の文字列を取る:文字列内の特定の文字のインデックスを追跡する最も効率的な方法は何ですか?

「速い茶色のキツネ」

今迅速で、qは、文字列(0から始まる)のインデックス4であり、キツネでfは指数であります16.ここで、ユーザーがこの文字列にもう少しテキストを入力するとします。

「非常に速い濃い茶色のキツネ」

今すぐqはインデックス9であり、fは、インデックスの元のインデックスを追跡する最も効率的な方法は何26

でありますどのくらいの文字がユーザによって追加されても、クイックではq、fではfで?

言語は私にとって重要ではありません。これは何よりも理論的な疑問です。あなたが望む言語を使用して、一般的に人気の高い現在の言語にしてください。

私が与えたサンプルの文字列は短いですが、私は効率的に任意のサイズの文字列を処理できる方法を望んでいます。したがってオフセットを使って配列を更新すると、短い文字列でも動作しますが、多くの文字が混乱することになります。

例では、文字列内の一意の文字のインデックスを検索していましたが、茶色のoとfoxのoなど、別の場所で同じ文字のインデックスを追跡できるようにしたいと考えています。だから、検索は問題外です。

私は答えが時間とメモリの両方で効率的であることを望んでいましたが、私がただ1つを選択しなければならない場合は、パフォーマンスの速度についてもっと気にしました。

答えて

2

文字列があり、その文字の一部が興味深いであるとします。物事を簡単にするために、インデックス0の文字は常に興味深いと言いましょう。それ以前に何かを加えないでください。—センチネル。 (興味深い文字、前の興味深い文字までの距離)のペアを書き留めます。文字列が「+非常にクイックダークブラウンフォックス」で、「クイック」と「fox」からのqに興味がある場合は、(+、0)、(q、10)、(f、17 )。

これをバランスの取れたバイナリツリーに入れて、その順序通りのトラバーサルが文字列の順序で文字列を与えるようにしました。 partial sums problemを認識できるようになりました。ノードに(文字、距離、合計)が含まれるようにツリーを拡張しました。合計は、左のサブツリー内のすべての距離の合計です。

このデータ構造を対数時間でクエリして更新できるようになりました。あなたは、文字の左Cn個文字を追加したことを言って

あなたは距離(C)+ = nは、その後Cのすべての親のための合計を行くと更新と言います。

あなたは合計を計算Cのインデックス(C)+合計(親(C))+合計(親(親(C)))+ ...

2

あなたの質問は少しあいまいです。すべての手紙の最初のインスタンスを把握していますか?その場合は、長さ26の配列が最適なオプションになる可能性があります。

あなたが持っているインデックスよりも低い位置に文字列を挿入するときは、挿入された文字列の長さに基づいてオフセットを計算するだけです。

1

すべてのデータ構造とインタラクションがすべての言語で同等に効率的かつ効果的であるとは限らないため、ターゲット言語を覚えておいても役に立ちます。

0

標準トリックが何であるかを尋ねること同様の状況で通常役立つのは、文字列の文字をバランスの取れたバイナリツリーに葉として保持することです。さらに、ツリーの内部ノードは、特定のノードをルートとするサブツリー内で発生する文字のセット(アルファベットが小さくて固定されている場合、それらはビットマップでもよい)を保持する必要があります。

この構造に文字を挿入または削除するには、O(log(N))操作(パス上のビットマップをrootに更新する)だけが必要で、文字の最初の出現を見つけるにはO - ビットマップに興味深い文字が含まれている一番左の子に行くと、ルートから降ります。

編集:内部ノードは、文字のインデックスを効率的に計算するために、表現されたサブツリー内の葉の数も保持する必要があります。

関連する問題