ホームページ バックエンド開発 C#.Net チュートリアル フィボナッチ数列もこのように書かれていることが分かりました。

フィボナッチ数列もこのように書かれていることが分かりました。

Jul 27, 2018 am 10:49 AM
c#

Baidu には「フィボナッチの非再帰記述」に対する回答がたくさんありますが、第一に難しすぎて理解できないこと、第二に再帰とパフォーマンスが似ていることなど、満足のいくものではありません。

フィボナッチ数列に関して言えば、初心者のプログラマであっても技術のベテランであっても、最初に思い浮かぶのは間違いなく再帰的な記述方法です。そして、技術のベテランとプログラムの初心者の違いは、計算の繰り返しを減らすために再帰の結果を保存することを考えるかどうかです。これらは非常に一般的な演算ですが、フィボナッチ数列が非再帰的な方法でも記述できると考えたことはありますか?
Baidu には「フィボナッチの非再帰記述」に対する回答がたくさんありますが、第一に難しすぎて理解できないこと、第二に再帰とパフォーマンスが似ていることなど、満足のいくものではありません。最初は、再帰呼び出しのコールスタックをシミュレートするものであれば、自分でも作成したいと思っていましたが、この考えは少し当たり前のことであり、作成されるプログラムも非常に複雑です。どうやってするの?このとき、ツリーの深さ優先走査が便利です。
最初に、ツリー ノードを定義します。
public class Node
        {
            public Node(long value, bool visited)
            {
                Value = value;
                Visited = visited;
            }

            public long Value { get; set; }//存放结点的值
            public bool Visited { get; set; }
        }
ログイン後にコピー

その後、DFS のスタックの書き方を楽しく学ぶことができます

  public static long Fblc(int n)
        {
            Stack<Node> s = new Stack<Node>();
            s.Push(new Node(n, false));
            long sum = 0;
            long[] childrenResultMemo = new long[n+1];
            childrenResultMemo[0] = 1;
            childrenResultMemo[1] = 1;
            //long children = 0;
            while (s.Any())
            {
                var cur = s.Pop();
             
                    if (cur.Visited == false)
                    {
                        if (childrenResultMemo[cur.Value] == 0)
                        {
                            cur.Visited = true;
                            if (childrenResultMemo[cur.Value - 1] != 0 && childrenResultMemo[cur.Value - 2] != 0)
                            {
                                var result = childrenResultMemo[cur.Value - 1] + childrenResultMemo[cur.Value - 2];
                                childrenResultMemo[cur.Value] = result;
                                sum += result;
                                s.Push(cur);
                            }
                            else
                            {
                                s.Push(cur);
                                s.Push(new Node(cur.Value - 1, false));
                                s.Push(new Node(cur.Value - 2, false));
                            }
                        }
                        else
                        {
                            sum += childrenResultMemo[cur.Value];//保存子树结果的优化,会有个特殊情况要处理
                        }
                        
                    }
                   
                
            }

            return sum;
        }
ログイン後にコピー

上記のアルゴリズムの中心的な考え方は、トラバースすることです。スタックを呼び出してスタックをポップアウトします。最上位の要素が訪問されている場合 (visited が true)、スキップします (上記のコードはサブツリー結果の保存の最適化を使用しています。処理される特別なケースがあります。これについては以下で詳しく説明します)。 ; それ以外の場合、現在の親ノード 訪問済みマークは true、つまり訪問されてスタックにプッシュされたことを意味し、その後、そのすべての子ノードがスタックにプッシュされます。

この考え方に従うと、作成するコードは上記とは異なります。コードの量ははるかに少なく、より簡潔になります。ただし、アルゴリズムの複雑さは再帰的アルゴリズムの複雑さと同様になります。計算が繰り返されるため、書き込みます。

何をすべきでしょうか? 解決策は 1 つだけです。空間を時間と交換し、サブツリーの結果を保存します。対応するサブツリーが計算され、結果が得られている場合、次のサブツリーの深さはトラバースしません。結果を直接使用します。サブツリーの結果を配列に保存します。

long[] childrenResultMemo = new long[n+1];
ログイン後にコピー

通常、サブツリーにすでに結果がある場合、論理的にはそのサブツリーにアクセスする必要があります。ただし、先頭にサブツリー 0 とサブツリー 1 がある特殊なケースもあります:

childrenResultMemo[0] = 1;
childrenResultMemo[1] = 1;
ログイン後にコピー

この特殊なケースのブランチに結果を追加するだけです:

sum += childrenResultMemo[cur.Value];
ログイン後にコピー

この書き方はどうでしょうか?めったに見られない?実際、フィボナッチ数列の評価プロセスは、ツリーの深さ優先の走査に似ています。したがって、深さ優先トラバーサルの実装である限り、完全に実現可能です。

関連記事:

Python でフィボナッチ数列の例を出力

#PHP でフィボナッチ数列を実装

関連動画:

データ構造の冒険 - キューの章

以上がフィボナッチ数列もこのように書かれていることが分かりました。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C# を使用した Active Directory C# を使用した Active Directory Sep 03, 2024 pm 03:33 PM

C# を使用した Active Directory のガイド。ここでは、Active Directory の概要と、C# での動作方法について、構文と例とともに説明します。

C# シリアル化 C# シリアル化 Sep 03, 2024 pm 03:30 PM

C# シリアル化のガイド。ここでは、C# シリアル化オブジェクトの導入、手順、作業、例についてそれぞれ説明します。

C# の乱数ジェネレーター C# の乱数ジェネレーター Sep 03, 2024 pm 03:34 PM

C# の乱数ジェネレーターのガイド。ここでは、乱数ジェネレーターの仕組み、擬似乱数の概念、安全な数値について説明します。

C# データ グリッド ビュー C# データ グリッド ビュー Sep 03, 2024 pm 03:32 PM

C# データ グリッド ビューのガイド。ここでは、SQL データベースまたは Excel ファイルからデータ グリッド ビューをロードおよびエクスポートする方法の例について説明します。

C# のパターン C# のパターン Sep 03, 2024 pm 03:33 PM

C# のパターンのガイド。ここでは、C# のパターンの概要と上位 3 種類について、その例とコード実装とともに説明します。

C# の素数 C# の素数 Sep 03, 2024 pm 03:35 PM

C# の素数ガイド。ここでは、C# における素数の導入と例を、コードの実装とともに説明します。

C# の階乗 C# の階乗 Sep 03, 2024 pm 03:34 PM

C# の Factorial のガイド。ここでは、C# での階乗の概要について、さまざまな例とコード実装とともに説明します。

マルチスレッドと非同期C#の違い マルチスレッドと非同期C#の違い Apr 03, 2025 pm 02:57 PM

マルチスレッドと非同期の違いは、マルチスレッドが複数のスレッドを同時に実行し、現在のスレッドをブロックせずに非同期に操作を実行することです。マルチスレッドは計算集約型タスクに使用されますが、非同期はユーザーインタラクションに使用されます。マルチスレッドの利点は、コンピューティングのパフォーマンスを改善することですが、非同期の利点はUIスレッドをブロックしないことです。マルチスレッドまたは非同期を選択することは、タスクの性質に依存します。計算集約型タスクマルチスレッド、外部リソースと相互作用し、UIの応答性を非同期に使用する必要があるタスクを使用します。

See all articles