タグ付けされた質問 「data-structures」

アルゴリズムで有利に使用できるようにデータを保存する方法に関する質問。

5
同じ目的に役立つさまざまなアルゴリズム/データ構造を学ぶ理由は何ですか?
私は学部生だったので、この質問について疑問に思っていました。これは一般的な質問ですが、以下の例で詳しく説明します。 私は多くのアルゴリズムを見てきました-例えば、最大流量の問題については、問題を解決できる3つのアルゴリズムを知っています:Ford-Fulkerson、Edmonds-Karp&Dinic、Dinicが最も複雑です。 データ構造(たとえば、ヒープ)には、バイナリヒープ、二項ヒープ、およびフィボナッチヒープがあり、フィボナッチヒープは全体的な複雑さが最適です。 私を混乱させているのは、すべてを知る必要がある理由はありますか?なぜ最高の複雑さを学び、慣れるだけではありませんか? すべてを知っているのが最善だと知っています。BでなくAを使用することでしか解決できない問題/アルゴリズムなど、「より有効な」理由があることを知りたいだけです。


4
(いつ)ハッシュテーブルルックアップはO(1)ですか?
ハッシュテーブルルックアップは一定の時間で動作するとよく言われます。ハッシュ値を計算すると、配列ルックアップのインデックスが得られます。しかし、これは衝突を無視します。最悪の場合、すべてのアイテムが同じバケットに到着し、ルックアップ時間は線形()になります。Θ(n)Θ(n)\Theta(n) ハッシュテーブルルックアップを本当にすることができるデータの条件はありますか?それは平均的にのみですか、またはハッシュテーブルにO (1 )最悪のケースルックアップを含めることができますか?O(1)O(1)O(1)O(1)O(1)O(1) 注:ここではプログラマーの視点から来ています。ハッシュテーブルにデータを格納すると、ほとんど常に文字列またはいくつかの複合データ構造であり、データはハッシュテーブルの有効期間中に変更されます。したがって、完璧なハッシュについての答えはありがたいですが、それらはかわいいですが、逸話的であり、私の観点からは実用的ではありません。 PSフォローアップ:ハッシュテーブル操作O(1)はどのようなデータですか?

4
ハッシュ関数でmodとして素数を使用するのが最適なのはなぜですか?
1〜100のキー値のリストがあり、それらを11個のバケットの配列に整理したい場合、mod関数を作成するように教えられました。 H=kmod 11H=kmod 11 H = k \bmod \ 11 これで、すべての値が9行に次々と配置されます。たとえば、最初のバケットには0、11、22 0,11,22…0,11,22…0, 11, 22 \dotsます。2番目では1,12,23…1,12,23…1, 12, 23 \dotsなどがあります。 悪い子になって、ハッシュ関数として非プライムを使用することにしたとしましょう-テイク12.ハッシュ関数の使用 H=kmod 12H=kmod 12 H = k \bmod \ 12 値をハッシュテーブルにつながる0,12,24…0,12,24…0, 12, 24 \dots 最初のバケットで、1,13,25…1,13,25…1, 13, 25 \dots等秒でのように。 本質的には同じものです。衝突を減らさなかったし、素数ハッシュコードを使用して物事をうまく分散させることもしなかったので、それがどのように有益であるかわかりません。

4
赤黒の木はなぜそんなに人気があるのですか?
私が見るところはどこでも、データ構造は赤黒木を使用して実装されているようです(std::setC ++、SortedDictionaryC#などで) アルゴリズムクラスで(a、b)、赤黒、AVLの各ツリーをカバーしたので、次のようになりました(教授に尋ねたり、数冊の本を読んだり、グーグルで調べたりすることからも)。 AVLツリーの平均深度は赤黒ツリーよりも小さいため、AVLツリーの値の検索は一貫して高速です。 赤黒木は、AVL木よりもバランスをとるための構造的な変化が少ないため、挿入/削除の速度が向上する可能性があります。これは、ランタイムと実装に大きく依存するため、これはツリーの構造変更のコストに依存するため、潜在的に言っています(ツリーが不変の場合、関数型言語でも完全に異なる可能性があります) AVLと赤黒木を比較する多くのオンラインベンチマークがありますが、私が驚いたのは、私の教授が基本的に次のいずれかを行うと言ったということです。 パフォーマンスについてそれほど気にかけない場合もあります。その場合、ほとんどの場合、AVLと赤黒の10〜20%の違いはまったく問題になりません。 または、パフォーマンスに本当に関心があります。この場合、AVLツリーと赤黒ツリーの両方を捨てて、Bツリーを使用します。Bツリーは、より良く機能するように調整できます(または(a、b)ツリー、私は)これらすべてを1つのバスケットに入れます。) その理由は、Bツリーがメモリにデータをよりコンパクトに格納するため(1つのノードに多くの値が含まれる)、キャッシュミスがはるかに少なくなるためです。また、ユースケースに基づいて実装を微調整し、Bツリーの順序をCPUキャッシュサイズなどに依存させることもできます。 問題は、実際の最新のハードウェアでの検索ツリーのさまざまな実装の実際の使用状況を分析するソースがほとんど見つからないことです。私はアルゴリズムに関する多くの本を調べましたが、異なるツリーバリアントを一緒に比較するものは見つかりませんでした。実際のプログラムで。) そうは言っても、上記で述べたことに基づいて、Bツリーがそれらを上回るはずであるときに、どこでも赤黒ツリーが使用されている特定の理由がありますか?(私が見つけることができる唯一のベンチマークとして、http://lh3lh3.users.sourceforge.net/udb.shtmlも示していますが、それは特定の実装の問題である可能性があります)。それとも、実装がかなり簡単であるために、誰もが赤黒ツリーを使用する理由、またはそれを別の言葉で言うと、実装が難しいのはなぜですか? また、関数型言語の領域に移動すると、これはどのように変わりますか?ClojureとScalaはどちらもHash配列にマップされた tryを使用しているようで、Clojureは32の分岐係数を使用しています。

9
抽出を持つ優先度キューが存在しますか?
プライオリティキューインターフェイスを実装するデータ構造は非常に多くあります。 挿入:構造に要素を挿入します Get-Min:構造内の最小要素を返します Extract-Min:構造内の最小要素を削除します このインターフェイスを実装する一般的なデータ構造は、(最小)ヒープです。 通常、これらの操作の(償却)実行時間は次のとおりです。 挿入:(時々O(log n ))O(1)O(1)\mathcal{O}(1)O(ログn )O(log⁡n)\mathcal{O}(\log n) Get-Min:O(1)O(1)\mathcal{O}(1) Extract-Min:O(ログn )O(log⁡n)\mathcal{O}(\log n) フィボナッチヒープは、例えば、これらの実行中の時間を実現します。さて、私の質問は次のとおりです。 次の(償却)実行時間のデータ構造はありますか? 挿入:O(ログn )O(log⁡n)\mathcal{O}(\log n) Get-Min:O(1)O(1)\mathcal{O}(1) 抽出分:O(1)O(1)\mathcal{O}(1) ソートされた入力が与えられたときに時間でそのような構造を構築できる場合、例えば、o (nO(n)O(n)\mathcal{O}(n)交差点は、「通常の」優先度キューを使用する場合よりも厳密に高速です。o (nログn)o(nlog⁡n)o\left(\frac{n}{\log n}\right)

1
赤黒の木を想像してください。それを作成する挿入と削除のシーケンスは常にありますか?
次の赤黒ツリーの定義を想定してみましょう。 これは二分探索木です。 各ノードは赤または黒の色で表示されます。ルートは黒です。 エッジで接続された2つのノードを同時に赤にすることはできません。 wikiのように、NILリーフの適切な定義が必要です。NILの葉は黒く着色されています。 ルートから任意のNILリーフへのパスには、同じ数の黒いノードが含まれます。 質問 赤黒ツリーのinsertand delete操作を実装したとします。さて、あなたが有効な赤黒木を与えられたら、それを構築する一連の操作insertとdelete操作が常にありますか? 動機 この質問は、この質問とこの質問からの議論によって動機付けられています。ます。 個人的には、黒のノードだけで構成される有効な赤黒木を想像すると(完全にバランスの取れた木を想像していることを意味します)、それを構築するシーケンスinsertとdelete操作があると思います。しかしながら、 私はそれを正確に証明する方法がわかりません より一般的なケースにも興味があります

2
高速スペルチェッカーを構築するための効率的なデータ構造
私はかなり大きな辞書で動作するはずのスペルチェッカーを書こうとしています。Damerau-Levenshtein距離を使用して、スペルミスの単語に最も近い単語を判断するために使用する辞書データを効率的にインデックス化する方法が本当に必要です。 私は、スペースの複雑さとランタイムの複雑さとの間の最適な妥協点を提供するデータ構造を探しています。 インターネットで見つけたものに基づいて、使用するデータ構造のタイプに関していくつかのリードがあります。 トライ これは私の最初の考えであり、実装が非常に簡単に見えるため、高速なルックアップ/挿入を提供するはずです。Damerau-Levenshteinを使用した近似検索は、ここでも簡単に実装できるはずです。しかし、ポインタストレージでは多くのオーバーヘッドが発生する可能性が高いため、スペースの複雑さに関してはあまり効率的ではありません。 パトリシア・トライ 基本的にポインターを保存するコストを回避しているため、これは通常のトライよりもスペースを消費しないようですが、私が持っているような非常に大きな辞書の場合、データの断片化が少し心配です。 サフィックスツリー これについては定かではありませんが、テキストマイニングで便利だと思う人もいるようですが、スペルチェッカーのパフォーマンスの面で何が得られるのかはよくわかりません。 三項検索ツリー これらはかなり見栄えがよく、複雑さの点ではパトリシアトライスに近い(より良い?)はずですが、パトリシアトライスよりも良いか悪いかは分からないでしょう。 バーストツリー これは一種のハイブリッドのようであり、トライスなどに比べてどのような利点があるかはわかりませんが、テキストマイニングには非常に効率的であると何度か読みました。 このコンテキストで使用するのに最適なデータ構造と、他のデータ構造よりも優れている点についてフィードバックを受け取りたいと思います。スペルチェッカーにさらに適切なデータ構造が不足している場合、私も非常に興味があります。

11
コンピューターサイエンスのデータが離散的であると見なされるのはなぜですか?
データの「構造」はブール代数に完全に依存していることを理解していますが、 なぜデータは連続的なものではなく、離散的な数学的実体と見なされるのですか? これに関連する: 次元の連続したエンティティとしてデータを構造化する際に違反する欠点または不変条件は何ですか?rrr 私は学部の数学の学生なので、この分野の専門家ではないので、誰かが私に5歳のように説明してくれたら本当に感謝しています。

3
ハードウェア/実装は、アルゴリズムの時間/空間の複雑さに影響しますか?
私はCSの学生でもないので、これはばかげた質問かもしれませんが、どうか私に耐えてください... プレコンピューター時代では、引き出しの配列のようなものでのみ配列データ構造を実装できます。値を抽出する前に、対応するインデックスでドロワーを見つける必要があるため、配列検索の時間の複雑さはバイナリ検索を想定。O(log(n))O(log(n))O(log(n)) しかし、コンピューターの発明は大きな違いをもたらしました。最近のコンピューターはRAMから非常に高速に読み取ることができるため、配列ルックアップの時間の複雑さはと考えています(技術的にはそうではありません。O(1)O(1)O(1) 別の例は、Python辞書です。誤って記述されたオーバーロードマジックメソッド(または、途方もなく不運、つまり、多くのハッシュ衝突を伴うキーで辞書アクセスの複雑さを得るかもしれませんが、通常はと推定されます。この場合、時間の複雑さは、Python辞書のハッシュテーブル実装と、ハッシュ関数のキーの実装の両方に依存します。O(n)O(n)O(n)__hash__O(1)O(1)O(1) これは、ハードウェア/実装がアルゴリズムの時間の複雑さに影響する可能性があることを意味しますか?(両方の例はアルゴリズムではなくデータ構造に関するものですが、後者は前者に基づいて構築されており、データ構造の時間の複雑さを聞いたことがないため、ここでは「アルゴリズム」という用語を使用しています) 私にとって、アルゴリズムは抽象的かつ概念的であり、時間/空間の複雑さなどの特性は、特定の方法で実装されているかどうかによって影響されるべきではありませんが、そうですか?

2
基数ツリーとパトリシアの試行の違いは何ですか?
私は基数ツリー(別名圧縮試行)とパトリシア試行について学習していますが、実際に同じであるかどうかについて矛盾する情報を見つけています。基数ツリーは、ノードが唯一の子ノードである場合にノードをその親とマージすることにより、通常の(圧縮されていない)トライから取得できます。これはパトリシアの試みにも当てはまります。2つのデータ構造はどのように異なっていますか? たとえば、NISTは2つを同じものとしてリストします。 パトリシアツリー (データ構造) 定義:唯一の子であるノードがその親とマージされるトライのコンパクトな表現。 基数ツリーとも呼ばれます。 ウェブ上の多くの情報源は同じことを主張しています。しかし、どうやらパトリシアの試みは基数の木の特殊なケースです。ウィキペディアのエントリは言う: PATRICIAの試行は、基数が2の基数の試行です。つまり、キーの各ビットが個別に比較され、各ノードが双方向(つまり、左対右)ブランチになります。 私はこれを本当に理解していません。違いは、ルックアップを行う際の比較の方法だけですか?各ノードを「双方向ブランチ」にするにはどうすればよいですか?ALPHABET_SIZE与えられたノードに対して可能な限り多くのブランチがあるべきではありませんか? 誰かがこれを明確にすることはできますか?実用的な目的のために、基数の試行は通常、パトリシアの試行として実装されていますか?または、そのような一般化を行うことはできませんか?

1
ハッシュテーブルとバイナリツリー
辞書を実装する場合(「顧客IDで顧客データを検索したい」)、使用される一般的なデータ構造はハッシュテーブルとバイナリ検索ツリーです。たとえば、C ++ STLライブラリは(バランスのとれた)バイナリ検索ツリーを使用して辞書(マップと呼びます)を実装し、.NETフレームワークは内部でハッシュテーブルを使用することを知っています。 これらのデータ構造の長所と短所は何ですか?特定の状況で合理的な他のオプションはありますか? キーが強力な基礎構造を持っている場合、たとえば、キーがすべて1からnまでの整数である場合など、特に興味がないことに注意してください。

2
すべての赤黒の木のバランスが取れているわけではありませんか?
直感的に、「バランスの取れたツリー」は、各ノードの左右のサブツリーが「ほぼ同じ」数のノードを持たなければならないツリーでなければなりません。 もちろん、赤黒木*(最後の定義を参照)のバランスについて話すとき、実際には、それらは高さのバランスが取れており、その意味で、バランスが取れていることを意味します。 上記の直観を次のように形式化しようとするとします。 定義:バイナリツリーはμμ\mu -balanced と呼ばれ、、ノードごとに不等式0≤μ≤120≤μ≤120 \le \mu \leq \frac{1}{2}NNN μ≤|NL|+1|N|+1≤1−μμ≤|NL|+1|N|+1≤1−μ \mu \le \frac{|N_L| + 1}{|N| + 1} \le 1 - \mu がすべて保持され、上記のステートメントが失敗するノードがあります。は、および左サブツリー内のノードの数ですがルート(ルートを含む)であるツリーの下のノードの数です。μ′>μμ′>μ\mu' \gt \mu|NL||NL||N_L|NNN|N||N||N|NNN このトピックに関する文献のいくつかでは、これらはウェイトバランスツリーと呼ばれています。 ノードを持つバイナリツリーが -balanced(定数)である場合、ツリーの高さはであるため、適切な検索を維持できることがわかります。プロパティ。nnnμμ\muμ>0μ>0\mu \gt 0O(logn)O(log⁡n)\mathcal{O}(\log n) 質問は次のとおりです。 いくつかありますすべてのビッグ十分な赤黒木があるように、 -balancedは?μ>0μ>0\mu \gt 0μμ\mu 使用する赤黒木の定義(Cormenらによるアルゴリズムの紹介から): 各ノードが赤または黒に色付けされているバイナリ検索ツリー 根は黒です すべてのNULLノードは黒です ノードが赤の場合、その子は両方とも黒です。 各ノードについて、そのノードから子孫NULLノードへのすべてのパスには、同じ数の黒いノードがあります。 注:上記の -balancedの定義では、NULLノードはカウントしません。(私たちがそうするかどうかは問題ではないと思いますが)。μμ\mu

2
Cのvoid型がempty / bottom型と類似していないのはなぜですか?
ウィキペディアと私が見つけた他のソースはvoid、空のタイプではなくユニットタイプとしてリストCのタイプを見つけました。void空の/下の型の定義によりよく適合するように思えるので、この混乱を見つけます。 void私が知る限り、値は存在しません。 戻り値の型がvoidの関数は、関数が何も返さないため、何らかの副作用しか実行できないことを指定します。 タイプのポインターvoid*は、他のすべてのポインタータイプのサブタイプです。また、void*C との間の変換は暗黙的です。 最後の点voidに、空の型であることの引数としてのメリットがあるかどうかはわかりvoid*ませんvoid。 一方、voidそれ自体は他のすべてのタイプのサブタイプではありません。これは、タイプがボトムタイプであるための要件であると言えます。
28 type-theory  c  logic  modal-logic  coq  equality  coinduction  artificial-intelligence  computer-architecture  compilers  asymptotics  formal-languages  asymptotics  landau-notation  asymptotics  turing-machines  optimization  decision-problem  rice-theorem  algorithms  arithmetic  floating-point  automata  finite-automata  data-structures  search-trees  balanced-search-trees  complexity-theory  asymptotics  amortized-analysis  complexity-theory  graphs  np-complete  reductions  np-hard  algorithms  string-metrics  computability  artificial-intelligence  halting-problem  turing-machines  computation-models  graph-theory  terminology  complexity-theory  decision-problem  polynomial-time  algorithms  algorithm-analysis  optimization  runtime-analysis  loops  turing-machines  computation-models  recurrence-relation  master-theorem  complexity-theory  asymptotics  parallel-computing  landau-notation  terminology  optimization  decision-problem  complexity-theory  polynomial-time  counting  coding-theory  permutations  encoding-scheme  error-correcting-codes  machine-learning  natural-language-processing  algorithms  graphs  social-networks  network-analysis  relational-algebra  constraint-satisfaction  polymorphisms  algorithms  graphs  trees 

1
これらの文字列操作をサポートする「文字列スタック」データ構造はありますか?
次の操作を実行できる文字セット文字列セットを格納するデータ構造を探しています。文字列のセットSを格納するデータ構造としてD(S )を示します。ΣΣ\SigmaD(S)D(S)\mathcal{D}(S)SSS Add-Prefix-Set上に:いくつかのセットの所定のT大き定数によって制限され、その文字列の長さが一定で、戻りによって囲まれている文字列(空)の、D({ T Sを| T ∈ T 、S ∈ S } )。これらの境界定数は両方ともグローバルです。これらはすべての入力Tで同じです。D(S)D(S)\mathcal{D}(S)TTTD({ts | t∈T,s∈S})D({ts | t∈T,s∈S})\mathcal{D}( \{ t s\ |\ t \in T, s \in S\} )TTT Get-Prefixes上の:リターン{ | S ∈ S 、∈ Σ }。O (| Σ |)時間でその内容を列挙できる限り、このセットにどの構造が使用されるかはあまり気にしないことに注意してください。D(S)D(S)\mathcal{D}(S){a | as∈S,a∈Σ}{a | as∈S,a∈Σ}\{ a \ | \ as \in S, …

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