mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-15 08:26:06 +00:00
Re-translate the Japanese version (#1871)
* Retranslate Japanese docs with GPT-5.4 * Retranslate Japanese code with GPT-5.4
This commit is contained in:
@@ -1,56 +1,56 @@
|
||||
# アルゴリズムは至る所にある
|
||||
# アルゴリズムは至るところにある
|
||||
|
||||
「アルゴリズム」という言葉を聞くと、自然に数学を思い浮かべます。しかし、多くのアルゴリズムは複雑な数学を含まず、基本的な論理により多く依存しており、これは私たちの日常生活の至る所で見ることができます。
|
||||
「アルゴリズム」という言葉を聞くと、自然に数学を思い浮かべます。しかし実際には、多くのアルゴリズムは複雑な数学を必要とせず、むしろ基本的な論理に依存しており、その論理は私たちの日常生活のいたるところで見られます。
|
||||
|
||||
アルゴリズムについて正式に議論を始める前に、興味深い事実を共有する価値があります。**あなたは無意識のうちに多くのアルゴリズムを学び、日常生活でそれらを応用することに慣れています**。ここで、この点を証明するためにいくつかの具体的な例を挙げます。
|
||||
アルゴリズムを本格的に議論する前に、ひとつ面白い事実を共有しておきます。**あなたはすでに知らず知らずのうちに多くのアルゴリズムを身につけ、それらを日常生活に応用することに慣れているのです**。以下では、いくつかの具体例を挙げてこれを示します。
|
||||
|
||||
**例1:辞書の引き方**。英語の辞書では、単語がアルファベット順に並んでいます。$r$で始まる単語を探していると仮定すると、通常は以下の方法で行います:
|
||||
**例1:辞書を引く**。辞書では、各漢字に対応するピンインがあり、辞書はピンインのアルファベット順に並んでいます。ピンインの先頭文字が $r$ の字を探すと仮定すると、通常は次の図のような方法で行います。
|
||||
|
||||
1. 辞書を大体半分ぐらいのところで開き、そのページの最初の語彙を確認します。例えば$m$で始まる文字だとしましょう。
|
||||
2. $r$はアルファベットで$m$の後に来るので、前半を無視して、探索空間を後半に絞ります。
|
||||
3. $r$で始まる単語を見つけるまで、ステップ`1.`と`2.`を繰り返します。
|
||||
1. 辞書をおよそ半分のところまで開き、そのページの先頭文字を確認し、先頭文字が $m$ だとします。
|
||||
2. ピンインのアルファベット表では $r$ は $m$ の後にあるため、辞書の前半を除外し、探索範囲を後半に絞ります。
|
||||
3. ピンインの先頭文字が $r$ のページを見つけるまで、手順 `1.` と手順 `2.` を繰り返します。
|
||||
|
||||
=== "<1>"
|
||||

|
||||

|
||||
|
||||
=== "<2>"
|
||||

|
||||

|
||||
|
||||
=== "<3>"
|
||||

|
||||

|
||||
|
||||
=== "<4>"
|
||||

|
||||

|
||||
|
||||
=== "<5>"
|
||||

|
||||

|
||||
|
||||
辞書を引くことは、小学生にとって必須のスキルですが、実際には有名な「二分探索」アルゴリズムです。データ構造の観点から、辞書をソートされた「配列」と考えることができます。アルゴリズムの観点から、辞書で単語を探すために取られる一連の行動は、「二分探索」アルゴリズムと見なすことができます。
|
||||
辞書を引くという小学生の必須スキルは、実は有名な「二分探索」アルゴリズムそのものです。データ構造の観点では、辞書を整列済みの「配列」とみなせます。アルゴリズムの観点では、上記の一連の辞書引きの操作を「二分探索」とみなせます。
|
||||
|
||||
**例2:トランプの整理**。トランプをプレイするとき、手札を昇順に並べる必要があります。以下の過程で示されます。
|
||||
**例2:トランプを整理する**。カードゲームをするとき、毎回手札のトランプを小さい順に並べ替える必要があります。その流れは次の図のとおりです。
|
||||
|
||||
1. トランプを「整列済み」と「未整列」のセクションに分けます。最初は一番左のカードが既に整列していると仮定します。
|
||||
2. 未整列セクションからカードを1枚取り出し、整列済みセクションの正しい位置に挿入します。この後、左端の2枚のカードが整列します。
|
||||
3. すべてのカードが整列するまで、ステップ`2`を繰り返します。
|
||||
1. トランプを「整列済み」と「未整列」の2つの部分に分け、初期状態では一番左の1枚がすでに整列済みだとします。
|
||||
2. 未整列部分から1枚のトランプを取り出し、整列済み部分の正しい位置に挿入します。完了すると、左端の2枚は整列済みになります。
|
||||
3. 手順 `2.` を繰り返し、各ラウンドで未整列部分から1枚を整列済み部分へ挿入し、すべてのトランプが整列済みになるまで続けます。
|
||||
|
||||

|
||||

|
||||
|
||||
上記のトランプを整理する方法は、実質的に「挿入ソート」アルゴリズムであり、小さなデータセットに対して非常に効率的です。多くのプログラミング言語のソート関数には挿入ソートが含まれています。
|
||||
上記のトランプ整理の方法は、本質的には「挿入ソート」アルゴリズムです。これは小規模なデータ集合を処理する際に非常に効率的で、多くのプログラミング言語のソートライブラリ関数にも挿入ソートが使われています。
|
||||
|
||||
**例3:お釣りの計算**。スーパーマーケットで$69$の買い物をしたと仮定します。レジ係に$100$を渡すと、$31$のお釣りを提供する必要があります。この過程は以下の図で明確に理解できます。
|
||||
**例3:お釣りを出す**。スーパーで $69$ 元の商品を購入し、店員に $100$ 元渡したとすると、店員は $31$ 元のお釣りを返す必要があります。店員は自然に次の図のような考え方をします。
|
||||
|
||||
1. 選択肢は$31$以下の価値のある通貨で、$1$、$5$、$10$、$20$が含まれます。
|
||||
2. 選択肢から最大の$20$を取り出し、$31 - 20 = 11$が残ります。
|
||||
3. 残りの選択肢から最大の$10$を取り出し、$11 - 10 = 1$が残ります。
|
||||
4. 残りの選択肢から最大の$1$を取り出し、$1 - 1 = 0$が残ります。
|
||||
5. お釣りの計算が完了し、解答は$20 + 10 + 1 = 31$です。
|
||||
1. 選択肢は $31$ 元より小さい額面の貨幣で、$1$ 元、$5$ 元、$10$ 元、$20$ 元があります。
|
||||
2. 選択肢の中から最大の $20$ 元を取り出すと、残りは $31 - 20 = 11$ 元です。
|
||||
3. 残りの選択肢の中から最大の $10$ 元を取り出すと、残りは $11 - 10 = 1$ 元です。
|
||||
4. 残りの選択肢の中から最大の $1$ 元を取り出すと、残りは $1 - 1 = 0$ 元です。
|
||||
5. お釣りは完了し、内訳は $20 + 10 + 1 = 31$ 元です。
|
||||
|
||||

|
||||

|
||||
|
||||
記述されたステップでは、利用可能な最大の額面を使用して各段階で最良の選択肢を選ぶことで、効果的なお釣り計算戦略につながります。データ構造とアルゴリズムの観点から、このアプローチは「貪欲」アルゴリズムとして知られています。
|
||||
以上の手順では、各ステップでその時点で最善と思われる選択肢を取っています。つまり、できるだけ額面の大きい貨幣を使い、最終的に実行可能なお釣りの方案を得ています。データ構造とアルゴリズムの観点から見ると、この方法は本質的に「貪欲法」です。
|
||||
|
||||
料理の準備から宇宙旅行まで、ほぼすべての問題解決にはアルゴリズムが関わっています。コンピュータの出現により、メモリにデータ構造を格納し、CPUとGPUを呼び出してアルゴリズムを実行するコードを書くことができるようになりました。このようにして、現実世界の問題をコンピュータに移し、より効率的な方法でさまざまな複雑な問題を解決できます。
|
||||
料理を一品作ることから星間航行に至るまで、ほとんどあらゆる問題の解決にアルゴリズムは欠かせません。コンピュータの登場によって、プログラミングを通じてデータ構造をメモリに格納し、さらにコードを書いて CPU や GPU にアルゴリズムを実行させることが可能になりました。こうして、生活の中の問題をコンピュータに移し、より効率的な方法でさまざまな複雑な問題を解決できるのです。
|
||||
|
||||
!!! tip
|
||||
|
||||
データ構造、アルゴリズム、配列、二分探索などの概念についてまだ混乱している場合は、読み続けることをお勧めします。この本は、データ構造とアルゴリズムの理解の領域へと優しく導いてくれるでしょう。
|
||||
データ構造、アルゴリズム、配列、二分探索といった概念がまだ少し曖昧でも、そのまま読み進めてください。本書がデータ構造とアルゴリズムの知識の世界へと案内します。
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# アルゴリズムとの出会い
|
||||
# アルゴリズム入門
|
||||
|
||||

|
||||

|
||||
|
||||
!!! abstract
|
||||
|
||||
優雅な乙女が踊ります。データと絡み合い、アルゴリズムのメロディーに合わせてスカートをなびかせながら。
|
||||
|
||||
彼女があなたをダンスに誘います。彼女のステップに従って、論理と美に満ちたアルゴリズムの世界に入りましょう。
|
||||
一人の少女が軽やかに舞い、データと織り重なり合いながら、スカートの裾にはアルゴリズムの旋律がたなびいています。
|
||||
|
||||
彼女はあなたをこの舞いへと誘います。その足取りに続いて、論理と美しさに満ちたアルゴリズムの世界へ踏み入りましょう。
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
# まとめ
|
||||
|
||||
- アルゴリズムは日常生活にありふれており、思っているほどアクセスしにくく複雑なものではありません。実際、私たちは既に無意識のうちに多くのアルゴリズムを学び、生活の様々な問題を解決するために使用しています。
|
||||
- 辞書で単語を引く原理は二分探索アルゴリズムと一致しています。二分探索アルゴリズムは分割統治という重要なアルゴリズム概念を体現しています。
|
||||
- トランプを整理する過程は挿入ソートアルゴリズムと非常に似ています。挿入ソートアルゴリズムは小さなデータセットのソートに適しています。
|
||||
- 通貨でお釣りを計算するステップは本質的に貪欲アルゴリズムに従っており、各ステップでその時点での最良の選択をします。
|
||||
- アルゴリズムは有限時間内で特定の問題を解決するための段階的な指示のセットですが、データ構造はコンピュータでのデータの組織化と保存方法を定義します。
|
||||
- データ構造とアルゴリズムは密接に関連しています。データ構造はアルゴリズムの基礎であり、アルゴリズムはデータ構造の機能を活用するステージです。
|
||||
- データ構造とアルゴリズムをブロックの組み立てに例えることができます。ブロックはデータを表し、ブロックの形状と接続方法はデータ構造を表し、ブロックを組み立てるステップはアルゴリズムに対応します。
|
||||
### 要点の振り返り
|
||||
|
||||
- アルゴリズムは日常生活の至る所にあり、決して手の届かない難解な知識ではありません。実際、私たちは気づかないうちに多くのアルゴリズムを身につけ、生活のさまざまな問題を解決しています。
|
||||
- 辞書を引く原理は二分探索アルゴリズムと一致しています。二分探索アルゴリズムは分割統治という重要なアルゴリズム思想を体現しています。
|
||||
- トランプを整理する過程は挿入ソートアルゴリズムと非常によく似ています。挿入ソートアルゴリズムは小規模なデータ集合のソートに適しています。
|
||||
- 貨幣の釣り銭を求める手順の本質は貪欲アルゴリズムであり、各ステップでその時点で最善と思われる選択を取ります。
|
||||
- アルゴリズムとは、限られた時間内に特定の問題を解決するための一連の命令または操作手順であり、データ構造とは、コンピュータ内でデータを組織し保存する方法です。
|
||||
- データ構造とアルゴリズムは密接に結びついています。データ構造はアルゴリズムの土台であり、アルゴリズムはデータ構造に生命を吹き込みます。
|
||||
- データ構造とアルゴリズムは積み木の組み立てにたとえることができます。積み木はデータを表し、積み木の形や接続方法などはデータ構造を表し、積み木を組み立てる手順がアルゴリズムに対応します。
|
||||
|
||||
### Q & A
|
||||
|
||||
**Q**:プログラマーとして、日常の仕事でアルゴリズムを手動で実装する必要があることはめったにありません。最も一般的に使用されるアルゴリズムは、既にプログラミング言語とライブラリに組み込まれており、すぐに使用できます。これは、私たちが仕事で遭遇する問題が、カスタムアルゴリズム設計を必要とする複雑さのレベルにまだ達していないことを示唆していますか?
|
||||
**Q**:プログラマーとして、私は日常業務でアルゴリズムを使って問題を解決したことがありません。よく使うアルゴリズムはプログラミング言語にすべてカプセル化されており、そのまま使えばよいです。これは、仕事上の問題がまだアルゴリズムを必要とする段階に達していないことを意味するのでしょうか?
|
||||
|
||||
特定の仕事スキルが武術の「技」のようなものだとすれば、基礎科目は「内功」のようなものです。
|
||||
具体的な仕事のスキルを武術の「型」にたとえるなら、基礎科目はむしろ「内功」に近いものです。
|
||||
|
||||
アルゴリズム(およびその他の基礎科目)を学ぶ意義は、必ずしも仕事でそれらを一から実装することではなく、概念の確固たる理解に基づいて、より専門的な意思決定と問題解決を可能にし、それによって仕事の全体的な質を向上させることだと私は信じています。例えば、すべてのプログラミング言語には組み込みのソート関数があります:
|
||||
私は、アルゴリズム(およびその他の基礎科目)を学ぶ意義は、仕事でそれをゼロから実装することではなく、学んだ知識に基づいて問題解決の際に専門的な反応や判断を下せるようになり、その結果として仕事全体の品質を高めることにあると考えています。簡単な例を挙げると、どのプログラミング言語にもソート関数が組み込まれています。
|
||||
|
||||
- データ構造とアルゴリズムを学んでいない場合、どんなデータが与えられても、このソート関数に渡すだけかもしれません。スムーズに動作し、良いパフォーマンスを示し、問題がないように見えます。
|
||||
- しかし、アルゴリズムを学んだことがあれば、組み込みのソート関数の時間複雑度は通常$O(n \log n)$であることを理解しています。さらに、データが固定桁数の整数(学生IDなど)で構成されている場合、基数ソートのようなより効率的なアプローチを適用でき、時間複雑度をO(nk)に削減できます。ここでkは桁数です。大量のデータを処理する際、節約された時間は重要な価値に変わります — コストの削減、ユーザーエクスペリエンスの向上、システムパフォーマンスの向上。
|
||||
- もしデータ構造とアルゴリズムを学んでいなければ、どんなデータが与えられても、そのソート関数に任せてしまうかもしれません。問題なく動き、性能も悪くなく、一見すると特に問題はありません。
|
||||
- しかしアルゴリズムを学んでいれば、組み込みのソート関数の時間計算量が $O(n \log n)$ であることを知っています。さらに、与えられたデータが固定桁数の整数(例えば学籍番号)であれば、より効率の高い「基数ソート」を使って、時間計算量を $O(nk)$ に下げることができます。ここで $k$ は桁数です。データ量が非常に大きい場合、節約できた実行時間は大きな価値を生みます(コスト削減、体験向上など)。
|
||||
|
||||
エンジニアリングでは、多くの問題を最適に解決することは困難です。ほとんどは「準最適」解決策で対処されます。問題の難しさは、その固有の複雑さだけでなく、それに取り組む人の知識と経験にも依存します。専門知識と経験が深いほど、分析がより徹底的になり、問題をより優雅に解決できます。
|
||||
工学分野では、多くの問題で最適解に到達することは難しく、少なくない問題は「だいたい」解決されているにすぎません。問題の難しさは、一方では問題そのものの性質に依存し、他方ではそれを観測する人の知識の蓄積にも依存します。知識が充実し、経験が豊富であるほど、問題分析はより深くなり、問題はより洗練された形で解決できるようになります。
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
# アルゴリズムとは何か
|
||||
# アルゴリズムとは
|
||||
|
||||
## アルゴリズムの定義
|
||||
|
||||
<u>アルゴリズム</u>は、有限時間内で特定の問題を解決するための一連の指示またはステップです。以下の特徴があります:
|
||||
<u>アルゴリズム(algorithm)</u>とは、限られた時間内に特定の問題を解決するための一連の命令または操作手順であり、次のような特徴を持ちます。
|
||||
|
||||
- 問題が明確に定義されており、入力と出力の明確な定義が含まれています。
|
||||
- アルゴリズムは実行可能で、有限の回数のステップ、時間、メモリ空間内で完了できることを意味します。
|
||||
- 各ステップには明確な意味があります。同じ入力と条件の下で出力は一貫して同じです。
|
||||
- 問題が明確であり、入力と出力の定義がはっきりしています。
|
||||
- 実行可能であり、有限の手順、時間、メモリ空間で完了できます。
|
||||
- 各手順の意味が確定しており、同じ入力と実行条件では常に同じ出力になります。
|
||||
|
||||
## データ構造の定義
|
||||
|
||||
<u>データ構造</u>は、コンピュータ内でデータを組織し保存する方法で、以下の設計目標があります:
|
||||
<u>データ構造(data structure)</u>とは、データを整理して保存する方式であり、データの内容、データ間の関係、データの操作方法を含み、次のような設計目標があります。
|
||||
|
||||
- コンピュータのメモリを節約するために空間占有を最小化する。
|
||||
- データ操作を可能な限り高速にし、データのアクセス、追加、削除、更新などをカバーする。
|
||||
- 効率的なアルゴリズム実行を可能にするために、簡潔なデータ表現と論理情報を提供する。
|
||||
- 使用する空間をできるだけ少なくし、コンピュータのメモリを節約します。
|
||||
- データの操作をできるだけ高速にし、アクセス、追加、削除、更新などを含みます。
|
||||
- 簡潔なデータ表現と論理情報を提供し、アルゴリズムが効率よく動作できるようにします。
|
||||
|
||||
**データ構造の設計はバランスを取る行為であり、しばしばトレードオフが必要です**。一つの側面を改善したい場合、しばしば別の側面で妥協する必要があります。以下は2つの例です:
|
||||
**データ構造の設計はトレードオフに満ちた過程です**。ある面を改善したい場合、別の面で妥協が必要になることがよくあります。以下に 2 つの例を示します。
|
||||
|
||||
- 配列と比較して、連結リストはデータの追加と削除においてより便利ですが、データアクセス速度を犠牲にします。
|
||||
- 連結リストと比較して、グラフはより豊富な論理情報を提供しますが、より多くのメモリ空間が必要です。
|
||||
- 連結リストは配列に比べてデータの追加や削除がしやすい一方で、データアクセス速度を犠牲にしています。
|
||||
- グラフは連結リストに比べてより豊富な論理情報を提供しますが、より大きなメモリ空間を必要とします。
|
||||
|
||||
## データ構造とアルゴリズムの関係
|
||||
|
||||
以下の図に示すように、データ構造とアルゴリズムは高度に関連し、密接に統合されており、具体的には以下の3つの側面があります:
|
||||
以下の図のように、データ構造とアルゴリズムは高度に関連し、密接に結び付いており、具体的には次の 3 つの点に表れます。
|
||||
|
||||
- データ構造はアルゴリズムの基礎です。構造化されたデータ保存とアルゴリズムのためのデータ操作方法を提供します。
|
||||
- アルゴリズムはデータ構造に活力を注入します。データ構造だけではデータ情報を保存するだけです。アルゴリズムの応用によって、特定の問題を解決できます。
|
||||
- アルゴリズムは異なるデータ構造に基づいて実装できることが多いですが、実行効率は大きく異なることがあります。適切なデータ構造を選択することが鍵です。
|
||||
- データ構造はアルゴリズムの土台です。データ構造はアルゴリズムに対して、構造化して格納されたデータと、そのデータを操作する方法を提供します。
|
||||
- アルゴリズムはデータ構造に命を吹き込みます。データ構造そのものはデータ情報を保存するだけであり、アルゴリズムと組み合わせて初めて特定の問題を解決できます。
|
||||
- アルゴリズムは通常、異なるデータ構造に基づいて実装できますが、実行効率が大きく異なる場合があり、適切なデータ構造を選ぶことが重要です。
|
||||
|
||||

|
||||
|
||||
データ構造とアルゴリズムは、以下の図に示すように、ブロックのセットに例えることができます。ブロックセットには多数のピースが含まれ、詳細な組み立て説明書が付いています。これらの説明書に段階的に従うことで、複雑なブロックモデルを構築できます。
|
||||
データ構造とアルゴリズムは、以下の図に示す組み立てブロックのようなものです。1 セットのブロックには多くの部品が含まれるだけでなく、詳しい組み立て説明書も付いています。説明書に従って一歩ずつ操作すれば、精巧なブロック模型を組み立てられます。
|
||||
|
||||

|
||||

|
||||
|
||||
両者の詳細な対応関係は以下の表に示されています。
|
||||
両者の詳細な対応関係を次の表に示します。
|
||||
|
||||
<p align="center"> 表 <id> データ構造とアルゴリズムをブロックと比較 </p>
|
||||
<p align="center"> 表 <id> データ構造とアルゴリズムを組み立てブロックにたとえる </p>
|
||||
|
||||
| データ構造とアルゴリズム | ブロック |
|
||||
| ------------------------ | ----------------------------------------------------- |
|
||||
| 入力データ | 未組み立てのブロック |
|
||||
| データ構造 | ブロックの組織、形状、サイズ、接続などを含む |
|
||||
| アルゴリズム | ブロックを望ましい形状に組み立てる一連のステップ |
|
||||
| 出力データ | 完成したブロックモデル |
|
||||
| データ構造とアルゴリズム | 組み立てブロック |
|
||||
| -------------- | ---------------------------------------- |
|
||||
| 入力データ | まだ組み立てていないブロック |
|
||||
| データ構造 | ブロックの構成形式。形状、大きさ、接続方法などを含む |
|
||||
| アルゴリズム | ブロックを目標の形に組み上げる一連の操作手順 |
|
||||
| 出力データ | ブロック模型 |
|
||||
|
||||
データ構造とアルゴリズムはプログラミング言語から独立していることは注目に値します。この理由により、この本は複数のプログラミング言語での実装を提供できます。
|
||||
特筆すべき点として、データ構造とアルゴリズムはプログラミング言語から独立しています。だからこそ、本書では複数のプログラミング言語に基づく実装を提供できます。
|
||||
|
||||
!!! tip "慣習的な略語"
|
||||
!!! tip "慣習的な略称"
|
||||
|
||||
実生活の議論では、「データ構造とアルゴリズム」を単純に「アルゴリズム」と呼ぶことがよくあります。例えば、よく知られたLeetCodeアルゴリズム問題は、実際にはデータ構造とアルゴリズムの両方の知識をテストしています。
|
||||
実際の議論では、私たちは通常「データ構造とアルゴリズム」を略して「アルゴリズム」と呼びます。たとえば広く知られている LeetCode のアルゴリズム問題は、実際にはデータ構造とアルゴリズムの両方の知識を同時に問うています。
|
||||
|
||||
Reference in New Issue
Block a user