2

例として次の文字列を取り上げます。

「クイックブラウンフォックス」

現在、quickのqは文字列のインデックス4(0から開始)にあり、foxのfはインデックス16にあります。ここで、ユーザーがこの文字列にさらにテキストを入力するとします。

「非常に速いダークブラウンのキツネ」

ここで、qはインデックス9にあり、fはインデックス26にあります。

ユーザーが追加した文字数に関係なく、元のqのインデックスをquickで、fをfoxで追跡する最も効率的な方法は何ですか?

言語は私には関係ありません。これは何よりも理論上の質問なので、一般的に人気のある現在の言語を維持するために、必要な言語を使用してください。

私が提供したサンプル文字列は短いですが、任意のサイズの文字列を効率的に処理できる方法を望んでいます。したがって、オフセットを使用して配列を更新すると、短い文字列で機能しますが、多くの文字に行き詰まります。

この例では、文字列内の一意の文字のインデックスを探していましたが、茶色のoや狐のoなど、さまざまな場所で同じ文字のインデックスを追跡できるようにする必要もあります。したがって、検索は問題外です。

時間とメモリの両方で効率的な答えが得られることを望んでいましたが、1つだけを選択する必要がある場合は、パフォーマンスの速度を重視します。

4

4 に答える 4

2

あなたの質問は少し曖昧です-あなたはすべての手紙の最初の例を追跡することを探していますか?もしそうなら、長さ26の配列が最良のオプションかもしれません。

インデックスよりも低い位置で文字列にテキストを挿入する場合は常に、挿入された文字列の長さに基づいてオフセットを計算するだけです。

于 2008-08-30T16:51:04.573 に答える
2

文字列があり、その文字のいくつかが興味深いとしましょう。簡単にするために、インデックス 0 の文字は常に興味深いものであり、その前に何か (歩哨) を追加しないとします。(興味深い文字、前の興味深い文字までの距離)のペアを書き留めます。文字列が "+the very Quick dark brown Fox" で、'quick' の q と 'fox' の f に興味がある場合は、次のように記述します: (+,0), (q,10), (f,17 )。(記号 + はセンチネルです。)

次に、これらをバランスの取れたバイナリ ツリーに配置します。このバイナリ ツリーの順序どおりのトラバーサルにより、文字列に出現する順序で一連の文字が得られます。ここで、部分和の問題に気付くかもしれません。ノードに (文字、距離、合計) が含まれるようにツリーを拡張します。合計は、左側のサブツリー内のすべての距離の合計です。(したがって、合計(x)=距離(左(x))+合計(左(x)))。

このデータ構造を対数時間でクエリおよび更新できるようになりました。

n文字を文字cの左側に追加したと言うには、 distance(c)+=n と言ってから、 cのすべての親の合計を更新します。

cのインデックスを調べるには、sum(c)+sum(parent(c))+sum(parent(parent(c)))+... を計算します。

于 2008-10-07T09:22:39.627 に答える
1

また、すべてのデータ構造と相互作用がすべての言語で同等に効率的かつ効果的であるとは限らないため、ターゲット言語を念頭に置いている場合にも役立ちます。

于 2008-08-30T17:25:14.910 に答える
0

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

この構造に文字を挿入または削除するには、O(log(N)) 操作 (ルートへのパス上のビットマップを更新する) のみが必要であり、文字の最初の出現を見つけるのにも O(log(N)) 操作が必要です。ルート。ビットマップに興味深い文字が含まれている左端の子を探します。

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

于 2008-10-07T09:49:10.600 に答える