mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-24 09:07:14 +00:00
deploy
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+1484
-584
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
|
||||
<meta name="description" content="アニメーションで図解、ワンクリック実行のデータ構造とアルゴリズムチュートリアル">
|
||||
<meta name="description" content="アニメーション図解とワンクリック実行コードで学べるデータ構造とアルゴリズムの入門書">
|
||||
|
||||
|
||||
<meta name="author" content="krahets">
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
|
||||
<title>第 6 章 ハッシュ表 - Hello アルゴリズム</title>
|
||||
<title>第 6 章 ハッシュテーブル - Hello アルゴリズム</title>
|
||||
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<path
|
||||
d="M480 32c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9L381.7 53c-48 48-113.1 75-181 75H192 160 64c-35.3 0-64 28.7-64 64v96c0 35.3 28.7 64 64 64l0 128c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V352l8.7 0c67.9 0 133 27 181 75l43.6 43.6c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V300.4c18.6-8.8 32-32.5 32-60.4s-13.4-51.6-32-60.4V32zm-64 76.7V240 371.3C357.2 317.8 280.5 288 200.7 288H192V192h8.7c79.8 0 156.5-29.8 215.3-83.3z" />
|
||||
</svg>
|
||||
<span>日本語版審閱者を募集しています!詳細は <a href="https://github.com/krahets/hello-algo/blob/main/ja/CONTRIBUTING.md">CONTRIBUTING.md</a> を参照してください。</span>
|
||||
<span>日本語版のレビュアーを募集しています。詳しくは <a href="/ja/chapter_appendix/contribution/">こちら</a> をご覧ください。</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -152,7 +152,7 @@
|
||||
<div class="md-header__topic" data-md-component="header-topic">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
第 6 章 ハッシュ表
|
||||
第 6 章 ハッシュテーブル
|
||||
|
||||
</span>
|
||||
</div>
|
||||
@@ -341,7 +341,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
序
|
||||
はじめに
|
||||
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
序
|
||||
はじめに
|
||||
|
||||
|
||||
</label>
|
||||
@@ -618,7 +618,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.1 アルゴリズムはどこにでもある
|
||||
1.1 アルゴリズムは至るところにある
|
||||
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 アルゴリズムとは何か
|
||||
1.2 アルゴリズムとは
|
||||
|
||||
|
||||
|
||||
@@ -783,7 +783,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.1 アルゴリズムの効率評価
|
||||
2.1 アルゴリズム効率の評価
|
||||
|
||||
|
||||
|
||||
@@ -1060,7 +1060,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.3 数値の符号化 *
|
||||
3.3 数値エンコーディング *
|
||||
|
||||
|
||||
|
||||
@@ -1088,7 +1088,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.4 文字の符号化 *
|
||||
3.4 文字エンコーディング *
|
||||
|
||||
|
||||
|
||||
@@ -1593,7 +1593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
第 6 章 ハッシュ表
|
||||
第 6 章 ハッシュテーブル
|
||||
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
第 6 章 ハッシュ表
|
||||
第 6 章 ハッシュテーブル
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1637,7 +1637,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.1 ハッシュ表
|
||||
6.1 ハッシュテーブル
|
||||
|
||||
|
||||
|
||||
@@ -1944,7 +1944,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.5 AVL木 *
|
||||
7.5 AVL 木 *
|
||||
|
||||
|
||||
|
||||
@@ -2107,7 +2107,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.2 ヒープ構築操作
|
||||
8.2 ヒープ構築
|
||||
|
||||
|
||||
|
||||
@@ -2493,7 +2493,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 二分探索の挿入点
|
||||
10.2 二分探索の挿入位置
|
||||
|
||||
|
||||
|
||||
@@ -2549,7 +2549,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 ハッシュ最適化戦略
|
||||
10.4 ハッシュによる最適化戦略
|
||||
|
||||
|
||||
|
||||
@@ -2577,7 +2577,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 探索アルゴリズムの再認識
|
||||
10.5 探索アルゴリズム再考
|
||||
|
||||
|
||||
|
||||
@@ -3115,7 +3115,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 分割統治アルゴリズム
|
||||
12.1 分割統治法
|
||||
|
||||
|
||||
|
||||
@@ -3171,7 +3171,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.3 木の構築問題
|
||||
12.3 二分木の構築問題
|
||||
|
||||
|
||||
|
||||
@@ -3199,7 +3199,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 ハノイの塔問題
|
||||
12.4 ハノイの塔の問題
|
||||
|
||||
|
||||
|
||||
@@ -3392,7 +3392,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.3 部分集合和問題
|
||||
13.3 部分和問題
|
||||
|
||||
|
||||
|
||||
@@ -3420,7 +3420,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Nクイーン問題
|
||||
13.4 n クイーン問題
|
||||
|
||||
|
||||
|
||||
@@ -3561,7 +3561,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 動的計画法の初歩
|
||||
14.1 動的計画法入門
|
||||
|
||||
|
||||
|
||||
@@ -3589,7 +3589,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.2 DP 問題の特性
|
||||
14.2 動的計画法の問題特性
|
||||
|
||||
|
||||
|
||||
@@ -3617,7 +3617,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.3 DP の解法の考え方
|
||||
14.3 動的計画法の問題解決の考え方
|
||||
|
||||
|
||||
|
||||
@@ -3645,7 +3645,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.4 0-1ナップサック問題
|
||||
14.4 0-1 ナップサック問題
|
||||
|
||||
|
||||
|
||||
@@ -3838,7 +3838,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.1 貪欲アルゴリズム
|
||||
15.1 貪欲法
|
||||
|
||||
|
||||
|
||||
@@ -4083,7 +4083,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.2 一緒に創作に参加する
|
||||
16.2 一緒に制作に参加しましょう
|
||||
|
||||
|
||||
|
||||
@@ -4273,16 +4273,16 @@
|
||||
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="6">第 6 章 ハッシュ表<a class="headerlink" href="#6" title="Permanent link">¶</a></h1>
|
||||
<p><img alt="ハッシュ表" class="cover-image" src="../assets/covers/chapter_hashing.jpg" /></p>
|
||||
<h1 id="6">第 6 章 ハッシュテーブル<a class="headerlink" href="#6" title="Permanent link">¶</a></h1>
|
||||
<p><img alt="ハッシュテーブル" class="cover-image" src="../assets/covers/chapter_hashing.jpg" /></p>
|
||||
<div class="admonition abstract">
|
||||
<p class="admonition-title">Abstract</p>
|
||||
<p>コンピューティングの世界において、ハッシュ表は賢い司書のようなものです。</p>
|
||||
<p>インデックス番号の計算方法を理解し、目的の本を迅速に取得することを可能にします。</p>
|
||||
<p>コンピュータの世界では、ハッシュテーブルは聡明な図書館員のような存在です。</p>
|
||||
<p>彼は請求記号の計算方法を知っており、そのため目的の本を素早く見つけられます。</p>
|
||||
</div>
|
||||
<h2 id="_1">章の内容<a class="headerlink" href="#_1" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
<li><a href="hash_map/">6.1 ハッシュ表</a></li>
|
||||
<li><a href="hash_map/">6.1 ハッシュテーブル</a></li>
|
||||
<li><a href="hash_collision/">6.2 ハッシュ衝突</a></li>
|
||||
<li><a href="hash_algorithm/">6.3 ハッシュアルゴリズム</a></li>
|
||||
<li><a href="summary/">6.4 まとめ</a></li>
|
||||
@@ -4333,7 +4333,7 @@ aria-label="フッター"
|
||||
<a
|
||||
href="./hash_map/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="次: 6.1 &nbsp; ハッシュ表"
|
||||
aria-label="次: 6.1 &nbsp; ハッシュテーブル"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -4341,7 +4341,7 @@ aria-label="フッター"
|
||||
次
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
6.1 ハッシュ表
|
||||
6.1 ハッシュテーブル
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
|
||||
<meta name="description" content="アニメーションで図解、ワンクリック実行のデータ構造とアルゴリズムチュートリアル">
|
||||
<meta name="description" content="アニメーション図解とワンクリック実行コードで学べるデータ構造とアルゴリズムの入門書">
|
||||
|
||||
|
||||
<meta name="author" content="krahets">
|
||||
@@ -117,7 +117,7 @@
|
||||
<path
|
||||
d="M480 32c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9L381.7 53c-48 48-113.1 75-181 75H192 160 64c-35.3 0-64 28.7-64 64v96c0 35.3 28.7 64 64 64l0 128c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V352l8.7 0c67.9 0 133 27 181 75l43.6 43.6c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V300.4c18.6-8.8 32-32.5 32-60.4s-13.4-51.6-32-60.4V32zm-64 76.7V240 371.3C357.2 317.8 280.5 288 200.7 288H192V192h8.7c79.8 0 156.5-29.8 215.3-83.3z" />
|
||||
</svg>
|
||||
<span>日本語版審閱者を募集しています!詳細は <a href="https://github.com/krahets/hello-algo/blob/main/ja/CONTRIBUTING.md">CONTRIBUTING.md</a> を参照してください。</span>
|
||||
<span>日本語版のレビュアーを募集しています。詳しくは <a href="/ja/chapter_appendix/contribution/">こちら</a> をご覧ください。</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -341,7 +341,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
序
|
||||
はじめに
|
||||
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
序
|
||||
はじめに
|
||||
|
||||
|
||||
</label>
|
||||
@@ -618,7 +618,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.1 アルゴリズムはどこにでもある
|
||||
1.1 アルゴリズムは至るところにある
|
||||
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 アルゴリズムとは何か
|
||||
1.2 アルゴリズムとは
|
||||
|
||||
|
||||
|
||||
@@ -783,7 +783,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
2.1 アルゴリズムの効率評価
|
||||
2.1 アルゴリズム効率の評価
|
||||
|
||||
|
||||
|
||||
@@ -1060,7 +1060,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.3 数値の符号化 *
|
||||
3.3 数値エンコーディング *
|
||||
|
||||
|
||||
|
||||
@@ -1088,7 +1088,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
3.4 文字の符号化 *
|
||||
3.4 文字エンコーディング *
|
||||
|
||||
|
||||
|
||||
@@ -1593,7 +1593,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
第 6 章 ハッシュ表
|
||||
第 6 章 ハッシュテーブル
|
||||
|
||||
|
||||
|
||||
@@ -1615,7 +1615,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
第 6 章 ハッシュ表
|
||||
第 6 章 ハッシュテーブル
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1637,7 +1637,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.1 ハッシュ表
|
||||
6.1 ハッシュテーブル
|
||||
|
||||
|
||||
|
||||
@@ -1778,7 +1778,7 @@
|
||||
<a href="#1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. 重要なポイント
|
||||
1. 重要ポイントの振り返り
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -2014,7 +2014,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.5 AVL木 *
|
||||
7.5 AVL 木 *
|
||||
|
||||
|
||||
|
||||
@@ -2177,7 +2177,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.2 ヒープ構築操作
|
||||
8.2 ヒープ構築
|
||||
|
||||
|
||||
|
||||
@@ -2563,7 +2563,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 二分探索の挿入点
|
||||
10.2 二分探索の挿入位置
|
||||
|
||||
|
||||
|
||||
@@ -2619,7 +2619,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 ハッシュ最適化戦略
|
||||
10.4 ハッシュによる最適化戦略
|
||||
|
||||
|
||||
|
||||
@@ -2647,7 +2647,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 探索アルゴリズムの再認識
|
||||
10.5 探索アルゴリズム再考
|
||||
|
||||
|
||||
|
||||
@@ -3185,7 +3185,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 分割統治アルゴリズム
|
||||
12.1 分割統治法
|
||||
|
||||
|
||||
|
||||
@@ -3241,7 +3241,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.3 木の構築問題
|
||||
12.3 二分木の構築問題
|
||||
|
||||
|
||||
|
||||
@@ -3269,7 +3269,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.4 ハノイの塔問題
|
||||
12.4 ハノイの塔の問題
|
||||
|
||||
|
||||
|
||||
@@ -3462,7 +3462,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.3 部分集合和問題
|
||||
13.3 部分和問題
|
||||
|
||||
|
||||
|
||||
@@ -3490,7 +3490,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Nクイーン問題
|
||||
13.4 n クイーン問題
|
||||
|
||||
|
||||
|
||||
@@ -3631,7 +3631,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 動的計画法の初歩
|
||||
14.1 動的計画法入門
|
||||
|
||||
|
||||
|
||||
@@ -3659,7 +3659,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.2 DP 問題の特性
|
||||
14.2 動的計画法の問題特性
|
||||
|
||||
|
||||
|
||||
@@ -3687,7 +3687,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.3 DP の解法の考え方
|
||||
14.3 動的計画法の問題解決の考え方
|
||||
|
||||
|
||||
|
||||
@@ -3715,7 +3715,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.4 0-1ナップサック問題
|
||||
14.4 0-1 ナップサック問題
|
||||
|
||||
|
||||
|
||||
@@ -3908,7 +3908,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
15.1 貪欲アルゴリズム
|
||||
15.1 貪欲法
|
||||
|
||||
|
||||
|
||||
@@ -4153,7 +4153,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
16.2 一緒に創作に参加する
|
||||
16.2 一緒に制作に参加しましょう
|
||||
|
||||
|
||||
|
||||
@@ -4299,7 +4299,7 @@
|
||||
<a href="#1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. 重要なポイント
|
||||
1. 重要ポイントの振り返り
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -4355,37 +4355,39 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="64">6.4 まとめ<a class="headerlink" href="#64" title="Permanent link">¶</a></h1>
|
||||
<h3 id="1">1. 重要なポイント<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<h3 id="1">1. 重要ポイントの振り返り<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<ul>
|
||||
<li>入力<code>key</code>が与えられると、ハッシュ表は<span class="arithmatex">\(O(1)\)</span>の時間で対応する<code>value</code>を取得でき、非常に効率的です。</li>
|
||||
<li>一般的なハッシュ表の操作には、クエリ、キー値ペアの追加、キー値ペアの削除、ハッシュ表の走査があります。</li>
|
||||
<li>ハッシュ関数は<code>key</code>を配列インデックスにマッピングし、対応するバケットにアクセスして<code>value</code>を取得できるようにします。</li>
|
||||
<li>2つの異なるキーがハッシュ化後に同じ配列インデックスになる場合があり、誤ったクエリ結果につながります。この現象はハッシュ衝突として知られています。</li>
|
||||
<li>ハッシュ表の容量が大きいほど、ハッシュ衝突の確率は低くなります。したがって、ハッシュ表のリサイズはハッシュ衝突を緩和できます。配列のリサイズと同様に、ハッシュ表のリサイズはコストが高いです。</li>
|
||||
<li>要素数をバケット数で割った負荷率は、ハッシュ衝突の深刻度を反映し、しばしばハッシュ表リサイズのトリガー条件として使用されます。</li>
|
||||
<li>連鎖法は各要素を連結リストに変換し、衝突するすべての要素を同じリストに格納することでハッシュ衝突に対処します。ただし、過度に長いリストはクエリ効率を低下させる可能性があり、リストを赤黒木に変換することで改善できます。</li>
|
||||
<li>オープンアドレス法は複数回のプローブを通してハッシュ衝突を処理します。線形プローブは固定ステップサイズを使用しますが、要素を削除できず、クラスタリングを起こしやすい傾向があります。多重ハッシュはプローブに複数のハッシュ関数を使用し、線形プローブと比較してクラスタリングを減らしますが、計算オーバーヘッドが増加します。</li>
|
||||
<li>異なるプログラミング言語はさまざまなハッシュ表実装を採用しています。例えば、Javaの<code>HashMap</code>は連鎖法を使用し、Pythonの<code>dict</code>はオープンアドレス法を採用しています。</li>
|
||||
<li>ハッシュ表では、決定性、高効率、均等分散を持つハッシュアルゴリズムが望まれます。暗号化では、ハッシュアルゴリズムは衝突耐性と雪崩効果も持つべきです。</li>
|
||||
<li>ハッシュアルゴリズムは通常、ハッシュ値の均等分散を保証し、ハッシュ衝突を減らすために、大きな素数を剰余として使用します。</li>
|
||||
<li>一般的なハッシュアルゴリズムには、MD5、SHA-1、SHA-2、SHA-3があります。MD5はファイル整合性チェックによく使用され、SHA-2は安全なアプリケーションとプロトコルで一般的に使用されます。</li>
|
||||
<li>プログラミング言語は通常、ハッシュ表のバケットインデックスを計算するために、データ型に対して組み込みのハッシュアルゴリズムを提供します。一般的に、不変オブジェクトのみがハッシュ可能です。</li>
|
||||
<li><code>key</code> を入力すると、ハッシュテーブルは <span class="arithmatex">\(O(1)\)</span> 時間で <code>value</code> を検索でき、非常に高効率である。</li>
|
||||
<li>一般的なハッシュテーブルの操作には、検索、キーと値のペアの追加、キーと値のペアの削除、ハッシュテーブルの走査などがある。</li>
|
||||
<li>ハッシュ関数は <code>key</code> を配列インデックスに写像し、それによって対応するバケットにアクセスして <code>value</code> を取得する。</li>
|
||||
<li>異なる 2 つの <code>key</code> が、ハッシュ関数を通した後に同じ配列インデックスになることがあり、検索結果の誤りを引き起こす。この現象をハッシュ衝突と呼ぶ。</li>
|
||||
<li>ハッシュテーブルの容量が大きいほど、ハッシュ衝突の確率は低くなる。そのため、ハッシュテーブルを拡張することでハッシュ衝突を緩和できる。配列の拡張と同様に、ハッシュテーブルの拡張操作のコストは大きい。</li>
|
||||
<li>負荷率は、ハッシュテーブル内の要素数をバケット数で割ったものと定義され、ハッシュ衝突の深刻さを反映する。ハッシュテーブル拡張を発動する条件としてよく用いられる。</li>
|
||||
<li>連鎖方式では、単一要素を連結リストに変換し、衝突したすべての要素を同じ連結リストに格納する。しかし、連結リストが長すぎると検索効率が低下するため、さらに連結リストを赤黒木に変換して効率を高めることができる。</li>
|
||||
<li>オープンアドレス法は複数回の探索によってハッシュ衝突を処理する。線形探索は固定のステップ幅を用いるが、要素を削除できず、クラスタリングが発生しやすいという欠点がある。二重ハッシュは複数のハッシュ関数を用いて探索するため、線形探索に比べてクラスタリングが起きにくいが、複数のハッシュ関数によって計算量が増える。</li>
|
||||
<li>プログラミング言語ごとに、異なるハッシュテーブル実装が採用されている。たとえば、Java の <code>HashMap</code> は連鎖方式を使用し、Python の <code>Dict</code> はオープンアドレス法を採用している。</li>
|
||||
<li>ハッシュテーブルでは、ハッシュアルゴリズムに決定性、高効率、均一分布という特徴が求められる。暗号学では、ハッシュアルゴリズムはさらに耐衝突性とアバランシェ効果も備えるべきである。</li>
|
||||
<li>ハッシュアルゴリズムは通常、大きな素数を法として用い、ハッシュ値の均一分布を最大限に保証してハッシュ衝突を減らす。</li>
|
||||
<li>一般的なハッシュアルゴリズムには MD5、SHA-1、SHA-2、SHA-3 などがある。MD5 はファイル完全性の検証によく用いられ、SHA-2 はセキュリティ用途やプロトコルでよく用いられる。</li>
|
||||
<li>プログラミング言語は通常、データ型に対して組み込みのハッシュアルゴリズムを提供し、ハッシュテーブル内のバケットインデックスの計算に用いる。通常、ハッシュ可能なのは不変オブジェクトだけである。</li>
|
||||
</ul>
|
||||
<h3 id="2-q-a">2. Q & A<a class="headerlink" href="#2-q-a" title="Permanent link">¶</a></h3>
|
||||
<p><strong>Q</strong>: ハッシュ表の時間計算量が<span class="arithmatex">\(O(n)\)</span>に悪化するのはいつですか?</p>
|
||||
<p>ハッシュ表の時間計算量は、ハッシュ衝突が深刻な場合に<span class="arithmatex">\(O(n)\)</span>に悪化する可能性があります。ハッシュ関数が適切に設計され、容量が適切に設定され、衝突が均等に分散されている場合、時間計算量は<span class="arithmatex">\(O(1)\)</span>です。プログラミング言語の組み込みハッシュ表を使用する場合、通常は時間計算量を<span class="arithmatex">\(O(1)\)</span>と考えます。</p>
|
||||
<p><strong>Q</strong>: なぜハッシュ関数<span class="arithmatex">\(f(x) = x\)</span>を使用しないのですか?これなら衝突を排除できます。</p>
|
||||
<p>ハッシュ関数<span class="arithmatex">\(f(x) = x\)</span>では、各要素が一意のバケットインデックスに対応し、これは配列と同等です。しかし、入力空間は通常出力空間(配列長)よりもはるかに大きいため、ハッシュ関数の最後のステップは配列長の剰余を取ることがよくあります。言い換えると、ハッシュ表の目標は、<span class="arithmatex">\(O(1)\)</span>のクエリ効率を提供しながら、より大きな状態空間をより小さなものにマッピングすることです。</p>
|
||||
<p><strong>Q</strong>: ハッシュ表がこれらの構造を使って実装されているにもかかわらず、なぜ配列、連結リスト、二分木よりも効率的になれるのですか?</p>
|
||||
<p>まず、ハッシュ表は時間効率が高いですが、空間効率は低いです。ハッシュ表のメモリの大部分は未使用のままです。</p>
|
||||
<p>次に、ハッシュ表は特定のユースケースでのみ時間効率が高いです。配列や連結リストを使用して同じ時間計算量で機能を実装できる場合、通常はハッシュ表を使用するよりも高速です。これは、ハッシュ関数の計算がオーバーヘッドを発生させ、時間計算量の定数因子が大きくなるためです。</p>
|
||||
<p>最後に、ハッシュ表の時間計算量は悪化する可能性があります。例えば、連鎖法では、連結リストや赤黒木で検索操作を実行し、これは依然として<span class="arithmatex">\(O(n)\)</span>時間に悪化するリスクがあります。</p>
|
||||
<p><strong>Q</strong>: 多重ハッシュにも要素を直接削除できないという欠陥がありますか?削除としてマークされた空間は再利用できますか?</p>
|
||||
<p>多重ハッシュはオープンアドレス法の一形態であり、すべてのオープンアドレス法には要素を直接削除できないという欠点があります。要素を削除済みとしてマークする必要があります。マークされた空間は再利用できます。ハッシュ表に新しい要素を挿入する際、ハッシュ関数が削除済みとしてマークされた位置を指している場合、その位置は新しい要素によって使用できます。これにより、ハッシュ表のプローブシーケンスを維持しながら、空間の効率的な使用が保証されます。</p>
|
||||
<p><strong>Q</strong>: なぜ線形プローブの検索プロセス中にハッシュ衝突が発生するのですか?</p>
|
||||
<p>検索プロセス中、ハッシュ関数は対応するバケットとキー値ペアを指します。<code>key</code>が一致しない場合、ハッシュ衝突を示します。したがって、線形プローブは正しいキー値ペアが見つかるか検索が失敗するまで、事前に決められたステップサイズで下方向に検索します。</p>
|
||||
<p><strong>Q</strong>: なぜハッシュ表のリサイズがハッシュ衝突を緩和できるのですか?</p>
|
||||
<p>ハッシュ関数の最後のステップは、出力を配列インデックス範囲内に保つために、配列長<span class="arithmatex">\(n\)</span>の剰余を取ることがよくあります。リサイズ時、配列長<span class="arithmatex">\(n\)</span>が変化し、キーに対応するインデックスも変化する可能性があります。以前に同じバケットにマッピングされていたキーが、リサイズ後に複数のバケットに分散される可能性があり、それによってハッシュ衝突が緩和されます。</p>
|
||||
<p><strong>Q</strong>:ハッシュテーブルの時間計算量が <span class="arithmatex">\(O(n)\)</span> になるのはどのような場合ですか?</p>
|
||||
<p>ハッシュ衝突が深刻な場合、ハッシュテーブルの時間計算量は <span class="arithmatex">\(O(n)\)</span> に劣化する。ハッシュ関数の設計が適切で、容量設定が合理的で、衝突が比較的均等な場合、時間計算量は <span class="arithmatex">\(O(1)\)</span> である。プログラミング言語組み込みのハッシュテーブルを使うとき、通常は時間計算量を <span class="arithmatex">\(O(1)\)</span> とみなす。</p>
|
||||
<p><strong>Q</strong>:なぜハッシュ関数 <span class="arithmatex">\(f(x) = x\)</span> を使わないのですか? そうすれば衝突は起きません。</p>
|
||||
<p><span class="arithmatex">\(f(x) = x\)</span> というハッシュ関数では、各要素は一意のバケットインデックスに対応し、これは配列と等価である。しかし、入力空間は通常、出力空間(配列長)よりはるかに大きいため、ハッシュ関数の最後のステップはたいてい配列長での剰余になる。言い換えると、ハッシュテーブルの目的は、大きな状態空間をより小さな空間に写像し、<span class="arithmatex">\(O(1)\)</span> の検索効率を提供することである。</p>
|
||||
<p><strong>Q</strong>:ハッシュテーブルの基礎実装は配列、連結リスト、二分木なのに、なぜそれらより高効率になり得るのですか?</p>
|
||||
<p>まず、ハッシュテーブルは時間効率が高くなる一方で、空間効率は低くなる。ハッシュテーブルには、かなりの部分で未使用のメモリが存在する。</p>
|
||||
<p>次に、時間効率が高くなるのは特定の利用場面に限られる。ある機能が同じ時間計算量で配列や連結リストによって実装できるなら、通常はハッシュテーブルより速い。これは、ハッシュ関数の計算にコストがかかり、時間計算量の定数項がより大きいからである。</p>
|
||||
<p>最後に、ハッシュテーブルの時間計算量は劣化する可能性がある。たとえば連鎖方式では、連結リストや赤黒木で検索操作を行うため、なお <span class="arithmatex">\(O(n)\)</span> 時間に劣化するリスクがある。</p>
|
||||
<p><strong>Q</strong>:二重ハッシュにも要素を直接削除できない欠点がありますか? 削除済みとマークした領域は再利用できますか?</p>
|
||||
<p>二重ハッシュはオープンアドレス法の一種であり、オープンアドレス法はいずれも要素を直接削除できないという欠点があるため、削除のマーク付けが必要になる。削除済みとマークされた領域は再利用できる。新しい要素をハッシュテーブルに挿入し、ハッシュ関数によって削除済みとマークされた位置を見つけた場合、その位置は新しい要素に使用できる。こうすることで、ハッシュテーブルの探索系列を変えずに保ちつつ、空間利用率も確保できる。</p>
|
||||
<p><strong>Q</strong>:なぜ線形探索では、要素を探すときにハッシュ衝突が発生するのですか?</p>
|
||||
<p>探索時には、ハッシュ関数で対応するバケットとキーと値のペアを見つけ、<code>key</code> が一致しないことが分かると、それはハッシュ衝突を意味する。そのため、線形探索法では事前に設定したステップ幅に従って順に探索し、正しいキーと値のペアを見つけるか、見つからずに終了するまで続ける。</p>
|
||||
<p><strong>Q</strong>:なぜハッシュテーブルの拡張でハッシュ衝突を緩和できるのですか?</p>
|
||||
<p>ハッシュ関数の最後のステップは、たいてい配列長 <span class="arithmatex">\(n\)</span> での剰余を取り、出力値を配列インデックスの範囲内に収めることである。拡張後は配列長 <span class="arithmatex">\(n\)</span> が変化し、<code>key</code> に対応するインデックスも変化する可能性がある。もともと同じバケットに入っていた複数の <code>key</code> は、拡張後には複数のバケットに割り当てられる可能性があり、それによってハッシュ衝突が緩和される。</p>
|
||||
<p><strong>Q</strong>:高効率な読み書きのためなら、配列を直接使えばよいのではないですか?</p>
|
||||
<p>データの <code>key</code> が連続した小範囲の整数であれば、配列を直接使えばよく、単純で高効率である。しかし <code>key</code> が別の型(たとえば文字列)の場合は、ハッシュ関数を用いて <code>key</code> を配列インデックスに写像し、さらにバケット配列を通じて要素を格納する必要がある。このような構造がハッシュテーブルである。</p>
|
||||
|
||||
<!-- Source file information -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user