タグ付けされた質問 「recursion」

自分自身の「小さい」インスタンスを使用して表現される関数、アルゴリズム、データ構造などのオブジェクトに関する質問。

4
末尾再帰とは何ですか?
再帰の一般的な概念を知っています。クイックソートアルゴリズムを勉強しているときに、テール再帰の概念に出会いました。MITの 18:30秒のクイックソートアルゴリズムのこのビデオでは、教授はこれが末尾再帰アルゴリズムであると述べています。末尾再帰が本当に何を意味するのかは私には明らかではありません。 誰かが適切な例で概念を説明できますか? ここで SOコミュニティによって提供されたいくつかの答え。

5
反復は再帰を置き換えることができますか?
私は、例えば、すべてのスタックオーバーフローの上で見てきたここでは、ここでは、ここでは、ここでは、ここで私は言及する気にしないいくつかの他、「用途再帰が唯一の反復を使用してプログラムに変換することができ、任意のプログラム」という。 はい、それは可能だと言った、非常に支持された答えを持つ、非常に支持されたスレッドさえありました。 今、私は彼らが間違っていると言っているのではありません。その答えは、コンピューティングについての私のわずかな知識と理解に反するだけです。 すべての反復関数は再帰として表現でき、ウィキペディアにはその旨の記述があると思います。しかし、その逆は真実ではないでしょう。1つには、非原始再帰関数を繰り返し表現できるかどうか疑問です。 また、ハイパーオペレーションを繰り返し表現できるかどうかも疑問です。 @YuvalFIlmusの質問に対する彼の答え(ちなみに私は理解できません)で、数学的操作のシーケンスを加算のシーケンスに変換することは不可能であると述べました。 YFの答えが確かに正しい場合(そうだと思いますが、彼の推論は私の頭の上にありました)、これはすべての再帰が反復に変換できるわけではないという意味ではありませんか?なぜなら、すべての再帰を反復に変換できれば、すべての操作を一連の加算として表現できるからです。 私の質問はこれです: すべての再帰を反復に変換できますか? 明るい高校生または最初の1年生が理解できる答えを与えてください。ありがとうございました。 PS原始再帰とは何かわかりません(アッカーマン関数については知っていますし、原始再帰ではありませんが、まだ計算可能です。それに関する私の知識は、アッカーマン関数のウィキペディアのページから得られます)。 PPS:答えが「はい」の場合、たとえば、非原始再帰関数の反復バージョンを記述できますか。たとえば、答えはアッカーマンです。理解するのに役立ちます。

5
再帰を使用する場合
ループではなく再帰を使用する(比較的)基本的な(大学1年生のCSレベルの学生と考えてください)インスタンスはいつですか?

6
GCDにとって最も効率的なものは何ですか?
ユークリッドのアルゴリズムは、正の整数のリストのGCD(最大公約数)を取得するための最適なアルゴリズムであることを知っています。しかし実際には、このアルゴリズムをさまざまな方法でコーディングできます。(私の場合、Javaを使用することにしましたが、C / C ++が別のオプションである可能性があります)。 プログラムで可能な限り最も効率的なコードを使用する必要があります。 再帰モードでは、次のように記述できます。 static long gcd (long a, long b){ a = Math.abs(a); b = Math.abs(b); return (b==0) ? a : gcd(b, a%b); } 反復モードでは、次のようになります。 static long gcd (long a, long b) { long r, i; while(b!=0){ r = a % b; a = b; b = …

2
入れ子になったコンポーネントを持つ帰納的なタイプの再帰的な定義
入れ子になっているが厳密に正の場所で再帰的に発生する誘導型を考えてください。たとえば、一般的なリストデータ構造を使用して子を格納するノードを使用した有限分岐を持つツリー。 Inductive LTree : Set := Node : list LTree -> LTree. これらのツリーとツリーのリストを再帰的に再帰的に定義する単純な方法は機能しません。以下sizeは、ノードの数を計算する関数の例です。 Fixpoint size (t : LTree) : nat := match t with Node l => 1 + (size_l l) end with size_l (l : list LTree) : nat := match l with | nil => 0 | cons …

3
ループが再帰よりも速いのはなぜですか?
実際には、再帰はループとして書くことができ(逆も同様です)、実際のコンピューターで測定すると、同じ問題に対してループが再帰よりも速いことがわかります。しかし、この違いをもたらす理論はありますか、それとも主に経験的ですか?

2
Yコンビネータは、カレー-ハワード通信と矛盾しますか?
Yコンビネータのタイプはです。Curry-Howard Correspondenceでは、型(a → a )→ aが存在するため、真の定理に対応しなければなりません。ただし、a → aは常にtrueであるため、Yコンビネータの型は定理aに対応するように見えますが、これは常にtrueとは限りません。どうすればいいの?(a→a)→a(a→a)→a(a \rightarrow a) \rightarrow a(a→a)→a(a→a)→a(a \rightarrow a) \rightarrow aa→aa→aa \rightarrow aaaa

3
再帰、スタック、またはキューなしでツリーをたどることができますか?
半年前、私はデータ構造クラスに座っていました。そこでは、再帰、スタック、キューなど(または他の同様のデータ構造)といくつかのポインターを使用せずに誰もがツリーを横断できる場合、教授は追加のクレジットを提供しました。私はその質問に対する明白な答えだと思ったものを思いついたが、それは教授によって最終的に受け入れられた。私は同じ学部の別の教授と一緒に離散数学クラスに座っていました。彼は、再帰、スタック、キューなどなしでツリーを横断することは不可能であり、私の解決策は無効であると主張しました。 それで、それは可能ですか、不可能ですか?なぜですか? 編集:明確化を追加するために、3つの要素(各ノードに保存されたデータと2つの子へのポインター)を持つバイナリツリーにこれを実装しました。私のソリューションは、わずかな変更を加えるだけでn項ツリーに拡張できます。 私のデータ構造の教師は、ツリーの変更に対して何の制約も課していませんでした。実際、彼自身の解決策は、子ポインターを使用してツリーを下に向けることであることがわかりました。私の離散数学教授は、ツリーの突然変異は、ツリーの数学的な定義によるとツリーではなくなったことを意味し、彼の定義は親へのポインタも排除することを言った-これは上記で解決した場合と一致します。

2
このプログラムは整数ごとに終了しますか?
GATE準備のパートテストでは、次の質問がありました。 f(n): if n is even: f(n) = n/2 else f(n) = f(f(n-1)) 「すべての整数で終了します」と答えました。なぜなら、いくつかの負の整数であっても、Stack Overflow Errorとして終了するからです。 しかし、私の友人は、これは実装されたコードではなく、単なる擬似コードであるため、いくつかの負の整数の場合は無限再帰になると反対しました。 正しい答えとその理由は?

2
consのどのプロパティにより、末尾再帰モジュロconsを排除できますか?
私は、基本的な末尾再帰除去の考え方に精通しています。そこでは、呼び出し自体の直接の結果を返す関数を反復ループとして書き直すことができます。 foo(...): # ... return foo(...) また、特別な場合として、再帰呼び出しがの呼び出しでラップされている場合、関数を書き換えることができることも理解していconsます。 foo(...): # ... return (..., foo(...)) これをcons許可するプロパティは何ですか?cons再帰的な末尾呼び出しを繰り返し書き換える能力を損なうことなく折り返すことができる以外の機能は何ですか? GCC(Clangではない)は、この「末尾再帰モジュロ乗算」の例を最適化できますが、どのメカニズムがこれを発見できるのか、またはどのように変換するのかは不明です。 pow(x, n): if n == 0: return 1 else if n == 1: return x else: return x * pow(x, n-1)

6
洗練された再帰アルゴリズムの例
有名な決定的線形時間選択アルゴリズム(中央値アルゴリズムの中央値)を友人に説明していました。 このアルゴリズムの再帰は(非常に単純ですが)非常に洗練されています。それぞれ異なるパラメーターを持つ2つの再帰呼び出しがあります。 このような興味深い再帰アルゴリズムの別の例を見つけようとしていましたが、見つけられませんでした。私が思いつく可能性のある再帰アルゴリズムはすべて、単純な末尾再帰または単純な分割統治(2つの呼び出しが「同じ」である)のいずれかです。 洗練された再帰の例をいくつか挙げていただけますか?

1
これは、再帰プロシージャを末尾再帰に変換する一般的な方法ですか?
私が変換する一般的な方法見つけたようだ任意の末尾再帰に再帰的な手順を: 追加の「結果」パラメーターを使用して、ヘルパーサブプロシージャを定義します。 プロシージャの戻り値に適用されるものをそのパラメータに適用します。 このヘルパープロシージャを呼び出して開始します。「結果」パラメーターの初期値は、再帰プロセスの終了点の値であるため、結果の反復プロセスは、再帰プロセスが縮小し始めるところから始まります。 たとえば、変換する元の再帰的手順は次のとおりです(SICP演習1.17)。 (define (fast-multiply a b) (define (double num) (* num 2)) (define (half num) (/ num 2)) (cond ((= b 0) 0) ((even? b) (double (fast-multiply a (half b)))) (else (+ (fast-multiply a (- b 1)) a)))) 変換された末尾再帰手続き(SICP演習1.18)は次のとおりです。 (define (fast-multiply a b) (define (double n) (* …

4
再帰的フィボナッチアルゴリズムの複雑さ
次の再帰フィボナッチアルゴリズムを使用します。 def fib(n): if n==0: return 0 elif n==1 return 1 return (fib(n-1)+fib(n-2)) fib(5)を見つけるために数値5を入力した場合、これが5を出力することがわかりますが、このアルゴリズムの複雑さをどのように調べることができますか?関連するステップを計算するにはどうすればよいですか?

1
ハノイの塔、ただし任意の初期および最終構成
最近、ハノイの塔のバリエーションであるこの問題に遭遇しました。 問題文: よく知られている問題、ハノイの塔の次のバリエーションを考えてみましょう。 我々は、与えられたタワーおよびサイズのM個のディスク1 、2 、3 、... 、Mいくつかの塔の上に積層します。あなたの目的は、管理できる限り少ない移動ですべてのディスクをk 番目のタワーに転送することですが、次のルールを考慮します。nnn1,2,3,…,m1,2,3,…,m1,2,3,\dots,mkthkthk^{\text{th}} 一度に1つのディスクのみを移動し、 大きいディスクを小さいディスクに移動しないでください。 最大で距離でタワー間のみを移動する。ddd (元の問題で制限: 及びM ≤ 100テストケースの数。≤ 1000年すべての問題は以下で解決することができると仮定することができる。 20000移動します。)3≤n≤10003≤n≤10003 \le n \le 1000m≤100m≤100m \le 100≤1000≤1000\le 1000200002000020000 面白いですね。ハノイ問題の古典的なタワーには、ソース、宛先、およびディスクをソースから宛先に移動するために使用される一時的なタワーがあります。そのサイトで提案された問題には、基本的に初期構成と最終構成があります。 この問題にどのように取り組みますか?

3
「帰納的に」と「再帰的に」は非常に類似した意味を持っていますか?
「帰納的に」と「再帰的に」は非常に似ていることを意味しますか? たとえば、決定された最初のk成分に基づいて最初のk + 1成分を決定することによりn次元ベクトルを決定し、最初の成分で初期化されるアルゴリズムがある場合、それは再帰的または帰納的に機能しますか?私は「再帰的に」使用してきましたが、今日誰かが「帰納的に」それを言いました。

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