2017-01-29 7 views
0

おそらく、アルゴリズムとデータ構造のほとんどのコースには、基底配列を因子で成長させることによって要素を追加する償却コストO(1)を持つ拡張可能な配列バッファが含まれます。命令型言語では、それはしばしばリストの最も効率的な実装です。 、線形連結と付加を伴う効果的に不変の配列支援配列

//imperative pattern: 
val buffer = new ArrayBuffer 
for (list <- lists) { 
    buffer append list 
} 

//functional pattern: 
foldLeft(Nil)((acc, list) => list :::acc)(lists) 

リンクリストと正常に動作します:

アレイ・バック・シーケンスはまだ利点場合でも、不変の多くを持っていますが、関数型言語では、バッファに繰り返し追加ループは、一般的に倍に置き換えられます純粋な実装では、配列のコストはO(n^n)です。 ArrayListのすべてのインスタンスが変化しないことが保証されたアレイfirstIndex .. firstIndex+length、一定の部分を表すことになりながら、そう

class ArrayList { 
    val array :Array 
    val firstIndex :Int 
    val length :Int 
    var ownsPrefix :Boolean 
    var ownsSuffix :Boolean 
} 

:効果的に不変なデータ構造を実装するために成長しているバッファのトリックを適応させることは可能ですそのセクション内のコンテンツは、いくつかのインスタンス間で共有することができます。 追加の可変フラグownsPrefixownsSuffixは、インスタンスが最後の要素の最初または最後の後に配列の要素の内容を自由に変更できるかどうかを定義します(配列の対応する部分は構造によって使用されません)。その場合、使用可能なスペースが十分にあり、連結操作では、追加/追加されたリストの要素をバッファの適切なフラグメントにコピーし、対応するフラグをオフにし、配列の結合セクションを表す値を返します。今バッファーを所有しています

これは、単一構造の繰り返し成長の最も一般的な使用例の問題を解決する簡単なトリックですが、実際には標準または一般的なライブラリで実装されていないことがわかりました。

私の質問は:それは名前を持っているのか、分析されているのか、それとも効率的なオープンソースの実装があるのでしょうか?私はそれを自分自身のためにスケーラで実装しています。ソースをオープンしたいのですが、ホイールを再開発することは嫌いで、既にそれについて発明された調整や最適化を組み込むことは喜んで行います。

答えて

1

私はこのようなことは見ませんでしたが、指の木が同様の必要性を満たすかもしれません。

TurinArrayList:

  • O(N)記憶
  • O(1)インデクシング
  • 償却O(1)追記/プリペンド
  • O(n)の連結

フィンガーツリー:

  • O(n)記憶
  • インデックス付け(mは最初または最後からの距離)
    O(1)(1)追記/プリペンド
  • 償却O(ログn)が連結

指木はまた、より良い共有を持っている最初のまたは最後

  • 償却Oを取得します。例えば、fingerTree,fingerTree :+ 1およびfingerTree :+ 2は、あなたの説明を理解している場合、arrayList,arrayList :+ 1、およびが常に少なくとも1つの完全配列をコピーするデザインとは異なり、正しく

    さらに簡単な実装、真の一定時間ランダムアクセス、CPUキャッシュに優しい連続したメモリレイアウトが必要です。

  • +0

    私はそれらを調べますが、Triesと少し似ています。はるかに汎用性の高い構造が一般的ですが、このケースは1つのことをうまくやっていることでした。配列の繰り返しと索引付けはメモリと時間的には効率的ですが、ここでの目標は一般的に効率的な連結ではありませんでしたが、典型的な使用パターンを利用してシーケンスの効率的な構築を実現しました。怠け者の私(最初に石を投げるように弦を連結したことはない)。 – Turin

    +0

    各ノードで可変のファンアウトを除いて、試行とフィンガーツリーの間には類似点はありません。フィンガーツリーは構造的にBツリーと似ていますが、最初と最後の要素にすばやくアクセスできる「フィンガー」といくつかの異なるバランスルールが追加されています。 – ephemient

    0

    私はこの具体的な考え方についてはわかりませんが、タイプシステムで値を変更するのが安全であることを指定するuniqueness typingと、参照カウントを使用してコピー作業を延期するcopy-on-writeに関連していますそれを変更する値。

    関連する問題