トップページ > プログラム > 2015年09月05日 > zGjt7Ia9

書き込み順位&時間帯一覧

1 位/165 ID中時間01234567891011121314151617181920212223Total
書き込み数00000001356455430010446859



使用した名前一覧書き込んだスレッド一覧
NAS6 ◆n3AmnVhjwc
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net

書き込みレス一覧

次へ>>
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
670 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 07:33:00.36 ID:zGjt7Ia9
>>656
おま、戻り値を使いまわしたら基本的に再帰じゃないの?。。。
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
673 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 08:00:20.87 ID:zGjt7Ia9
//r:ret,s:diff,n:n
int sigma(int r, int s, int n) {
 if (n < 1)return 0;
 if (n == 1) return r;
 return r + sigma(r + s, s, n - 1);
}
int sigma2(int s, int n) {
 if (n < 1)return 0;
 int r = 0, t = s;
 for (n--; 0 < n; n--, t += s) r = r + t;
 return r;
}
戻り値の使いまわしは基本的に再帰
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
675 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 08:53:27.64 ID:zGjt7Ia9
そそ、戻り値の使いまわしとスタック保存
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
676 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 08:59:50.82 ID:zGjt7Ia9
たとえば、シュミレーションゲームでユニットの移動範囲を調べる
とかの全検索は、どうやっても再帰
もちろんA*も再帰
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
678 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 09:03:26.20 ID:zGjt7Ia9
スタック保存の必要がなければループ文でいい
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
679 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 09:05:10.34 ID:zGjt7Ia9
>手順 (もしくはそれに相当するもの) を覚えている物が再帰。
これがスコープのスタック保存だろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
685 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 09:26:38.87 ID:zGjt7Ia9
sum=sum+iで
sum+iのsumはスタック保存値
sum=のsumがスタック保存(+上書き)
こういうのはループでも全然いいけど
スコープスタックを保存する必要があるなら、完全に再帰しかない
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
687 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 09:40:47.32 ID:zGjt7Ia9
いや再帰っつーのは終わるまで必ず自身がどの手順でそこの処理に居るのかが記録されてるから。
必要がないもくそもない

だから、スコープスタックを保存する必要がある時に、再帰を使う必要があるんですってば
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
688 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 09:57:57.73 ID:zGjt7Ia9
>>650

>>673
な感じなんだろ

ループは、スコープスタックを保存しなくていい時
再帰は、スコープスタックを保存しなければいけない時
再帰の文字通り、手順の戻り道を、覚えている必要があるかどうかだよ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
690 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:01:42.56 ID:zGjt7Ia9
バカは知りませんが関数呼び出しはコールスタックです
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
694 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:12:58.37 ID:zGjt7Ia9
//r:ret,s:diff,n:n
int sigma(int r, int s, int n) {
 if (n < 1)return 0;
 if (n == 1) return r;
 return r + sigma(r + s, s, n - 1);
}
これは全部、スタックに保存されてるよ
だから、
int sigma2(int s, int n) {
 if (n < 1)return 0;
 int r = 0, t = s;
 for (n--; 0 < n; n--, t += s) r = r + t;
 return r;
}
これに比べて、スタック保存分、オーバーロードしているけどね
ユニットの移動範囲とか、画像のフィリングとか、
ある点の周囲探索は、スタック保存の再帰関数にするのが一番いいだろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
695 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:16:27.86 ID:zGjt7Ia9
たとえば白黒ドットの囲まれた場所のある点からの塗りつぶしで
ループだけしか使わないバカがいるのか?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
698 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:21:49.47 ID:zGjt7Ia9
白黒ドットの囲まれた場所のある点からの塗りつぶしで
ループだけしか使わないで作れるなら作ってみろよ
ニヤニヤしながら見ててやるから
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
699 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:26:03.39 ID:zGjt7Ia9
>>697
え?コールスタックが再帰じゃないの?
それじゃ、関数を呼び出した後、元の位置に戻れないぞ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
702 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 10:34:15.27 ID:zGjt7Ia9
サブルーチンの呼び出しの後、
呼び出し元に復元(リターン)できなければ、
プログラムじゃねえよ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
706 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 11:00:37.95 ID:zGjt7Ia9
ttp://nas6.main.jp/secret/ContainerPtr.htm

ttp://nas6.main.jp/NAS6_tree_clct.h
//再帰構文例1
//再帰構文例2
は俺は両方再帰だと思って作ったけどな
>>700
みたいのは
//再帰構文例1
の構造だろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
707 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 11:05:54.33 ID:zGjt7Ia9
関数の自分自身を呼ばないと再帰関数じゃないっていうのは
頭が固いんじゃないの?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
708 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 11:10:08.71 ID:zGjt7Ia9
訂正
関数の自分自身を呼ばないと再帰処理じゃないっていうのは
頭が固いんじゃないの?
//再帰構文例1
は関数の自分自身を呼んでないけど、どう見ても再帰処理
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
714 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 11:55:26.05 ID:zGjt7Ia9
>>713
だからクラスの関数呼び出しなんて、ほとんど
this->が省略されているだけなんだが・・・
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
717 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 12:09:24.27 ID:zGjt7Ia9
アセンブリレベルが分からないと説明しようがないな
基本的にスタックでしか動かないし

ttp://www.math.kobe-u.ac.jp/~taka/asir-book-html/main/node65.html
再帰呼び出し、スタック
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
718 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 12:13:43.89 ID:zGjt7Ia9
>>717の大学教授にこれはループであって再帰ではないってかみついてこいよ
def xn2(N) {
 XN = 0;
 for (I=0; I<N; I++) {
  XN = 2*XN+1;
 }
 return(XN);
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
719 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 12:25:42.76 ID:zGjt7Ia9
int sum = 0;
 for(int i = 1; i <= 10; i++) {
  sum = sum + i;
}

な、これは再帰だろ、頭が悪いんだから、教授に迷惑をかけるなよ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
720 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 12:44:51.30 ID:zGjt7Ia9
戻り値を使いまわしたら基本的に再帰なんだよってはじめに書いておいた
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
721 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 12:56:18.37 ID:zGjt7Ia9
>>700
のも

新たなシードを決める際には、バッファ中のどのピクセルを選んでもよいのですが、
新しい順か、古い順かのどちらかに統一するのが普通でしょう。
バッファをスタック構造にすれば新しい順、キューにすれば古い順に自然に決まります。

これを読んでいないのか再帰じゃないと思ってるんだろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
723 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 13:14:58.05 ID:zGjt7Ia9
>>722
だから、戻り値を使って再帰呼び出ししているのと同じ事だろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
727 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 13:22:00.75 ID:zGjt7Ia9
>>725

>>717
のリンクで
正式には再帰で書くけど、
最適化してループで書くってようなことが書いてあるだろ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
728 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 13:26:52.77 ID:zGjt7Ia9
>>717
のリンクでも
>>694
でも
>これに比べて、スタック保存分、オーバーロードしているけどね
こういうわけで再帰をループに最適化するわけ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
730 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 13:41:26.99 ID:zGjt7Ia9
//等差数列
//定義に忠実に書いた場合
//r:ret,s:diff,n:n
int sigma(int r, int s, int n) {
 if (n < 1)return 0;
 if (n == 1) return r;
 return r + sigma(r + s, s, n - 1);
}
//メモリ使用量を最適化した場合
int sigma2(int s, int n) {
 if (n < 1)return 0;
 int r = 0, t = s;
 for (n--; 0 < n; n--, t += s) r = r + t;
 return r;
}
で、最適化されたのしか、教わらないし、理解できないのかな?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
731 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 13:48:39.57 ID:zGjt7Ia9
訂正

//等差数列
//定義に忠実に書いた場合
//r:ret,s:diff,n:n
int sigma(int r, int s, int n) {
 if (n < 1)return 0;
 if (n == 1) return r;
 return r + sigma(r + s, s, n - 1);
}
//メモリ使用量を最適化した場合
int sigma2(int s, int n) {
 if (n < 1)return 0;
 int r = 0, t = s;
 for (; 1 < n; n--, t += s) r = r + t;
 return r;
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
733 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 14:09:21.37 ID:zGjt7Ia9
漸化式で求めた全ての項を
参照する必要があるのならば
動的計画法を用いることはできない
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
736 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 14:42:48.35 ID:zGjt7Ia9
>>734
ああ、ごめんね
sigmaだから1〜nまでの等差数列の和だよ

漸化式の全ての項を使う
→全てのノードを使う時は動的計画法で最適化できないんよ
そのケースは、ある点からの周囲の経路を探索する場合
ディレクトリ探索だったり、塗りつぶしだったり、つまり全検索をかける場合
こういうのは再帰を使うだろうに
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
737 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 14:44:53.85 ID:zGjt7Ia9
つまり経路の全検索をかける場合
こういうのは再帰を使うだろうに
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
739 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 14:57:36.94 ID:zGjt7Ia9
>>734
sigmaだから1〜n-1までの等差s数列の和
s=3なら
sigma=3+6+9+12+・・・
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
740 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 15:08:23.80 ID:zGjt7Ia9
//1〜n-1までの等差s数列の和
//定義に忠実に書いた場合
//r:ret,s:diff,n:n
int sigma(int r, int s, int n) {
 if (n < 1)return 0;
 if (n == 1) return r;
 return r + sigma(r + s, s, n - 1);
}
//メモリ使用量を最適化した場合
int sigma2(int s, int n) {
 if (n < 1)return 0;
 int r = 0, t = s;
 for (; 1 < n; n--, t += s) r = r + t;
 return r;
}
べつにどっちで書けって言われても
項をスタックするかしないだけの違いだけど?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
744 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 15:19:27.30 ID:zGjt7Ia9
利点と欠点があって

再帰:書けない漸化式はない、項をスタックするからメモリを消費する
ループ:項の参照が少ない漸化式のみ書ける、項をスタックしないからメモリ使用量は少ない

そんだけ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
746 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 15:31:56.99 ID:zGjt7Ia9
>>745
ノード検索とか再帰のノード全てメモしてループするとか
素直に再帰を使っちゃいかんのかいな
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
750 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 18:40:37.54 ID:zGjt7Ia9
利点と欠点があって

再帰:書けない漸化式はない
項をスタックするからメモリを消費する

ループ:項の参照が少ない漸化式のみ書ける
あるいは項をメモする必要がある
項をスタックしないからメモリ使用量は少ない

そんだけ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
755 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 20:00:58.23 ID:zGjt7Ia9
double calcPI(double r, double s, double n) {
 double t = 1.0;
 if (s == 1) t = 2.0;
 if (n == 1) return r;
 return t * (r + calcPI(r * s / (2.0 * s + 1.0), s + 1, n - 1));
}
double calcPI2() {
 double sse = 0.00000000000001; double a = 0.125;
 double b = sqrt(a); double c = 1.0 + 3.0 * b;
 double d = sqrt(c); double e = 0.625;
 double f = d - e; d = 2 * d;
 b = f - b; c = c + f;
 double npow = 4;
 do {
  npow = 2 * npow;  f = (c + d) / 2;
  d = sqrt(c * d);  f = f - d;
  d = 2 * d;  b = b - f;  c = f + d;
 } while (sse < f);
 f = f * f / 4; c = c + d;
 return (c * c - f - f / 2) / (c * b - f) / npow;
}
どっちが簡単だと思う?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
756 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 20:25:21.94 ID:zGjt7Ia9
double calcPI(double r, double s, double n) {
 double t = 1.0;
 if (s == 1) t = 2.0;
 if (n == 1) return r;
 return t * (r + calcPI(r * s / (2.0 * s + 1.0), s + 1, n - 1));
}
double calcPI3(double n) {
 double r = 1.0;
 double s = 1.0;
 double t = 1.0;
 while (1 < n) {
  t = (t * s / (2.0 * s + 1.0));
  r = r + t;
  s += 1;
  n -= 1;
 }
 return 2.0 * r;
}
意地悪が過ぎたが、今度はマジ
どっちが可読性があるの?
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
757 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 20:34:20.88 ID:zGjt7Ia9
ああ、ちなみにπの漸化式は
2(1+(1/3)+(1/3)(2/5)+(1/3)(2/5)(3/7)+...)
だからね
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
758 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 20:49:22.97 ID:zGjt7Ia9
変数名がごっちゃにならないように書き直し
double calcPI(double r, double s, double n) {
 double u = 1.0;
 if (s == 1) u = 2.0;
 if (n == 1) return r;
 return u * (r + calcPI(r * s / (2.0 * s + 1.0), s + 1, n - 1));
}
double calcPI3(double n) {
 double r = 1.0;
 double s = 1.0;
 double t = 1.0;
 double u = 2.0;
 while (1 < n) {
  t = (t * s / (2.0 * s + 1.0));
  r = r + t;
  s += 1;
  n -= 1;
 }
 return u * r;
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
759 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 21:09:08.26 ID:zGjt7Ia9
完全に同じ処理にしたけど、どっちが楽なんだろうね?
double calcPI(double r, double s, double n) {
 double u = 1.0;
 if (s == 1) u = 2.0;
 if (n == 0) return r;
 return u * (r + calcPI(r * s / (2.0 * s + 1.0), s + 1, n - 1));
}
double calcPI3(double n) {
 double r = 1.0;
 double s = 1.0;
 double t = 1.0;
 double u = 1.0;
 while (0 < n) {
  t = t * s / (2.0 * s + 1.0);
  r = u * (r + t);
  s += 1;
  n -= 1;
 }
 u = 2.0;
 return u * r;
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
760 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 21:16:59.43 ID:zGjt7Ia9
我々は「軍国主義者」を打倒したと、我らが「軍事パレード」で宣言
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
762 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 21:55:59.06 ID:zGjt7Ia9
コンパイラ入れんのめんどくさいからパス
#include <iostream>

void init(int * p, int n) {
 for (; 0 < n; n--) p[n] = 0;
}
void disp(int * p, int n) {
 std::cout << std::endl;
 for (int i = 0; i < n; i++) std::cout << p[i] << " ";
 std::cout << std::endl;
}
int recUnit(int i, int j, int *a, int na, int *b, int nb) {
 if (i < na && j < nb) a[i] = b[j];
 else return i;
 return recUnit(i + 1, j + 1, a, na, b, nb);
}
void unit(int *a, int na, int *b, int nb, int *c, int nc) {
 int i;
 i = recUnit(0, 0, a, na, b, nb);
 recUnit(i, 0, a, na, c, nc);
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
763 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 21:56:37.35 ID:zGjt7Ia9
void unit2(int *a, int na, int *b, int nb, int *c, int nc) {
 int i, j;
 for (i = 0, j = 0; j < nb; i++, j++) if (i < na)a[i] = b[j];
 for (j = 0; j < nc; i++, j++) if (i < na)a[i] = c[j];
}
int main()
{
 int a[10], b[5] = { 0, 1, 2, 3, 4 }, c[5] = { 5, 6, 7, 8, 9 };
 init(a, 10); unit(a, 10, b, 5, c, 5); disp(a, 10);
 init(a, 10); unit2(a, 10, b, 5, c, 5); disp(a, 10);
 return 0;
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
764 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 22:03:28.78 ID:zGjt7Ia9
ミスった
#include <iostream>

void init(int * p, int n) {
 for (; 0 < n; n--) p[n - 1] = 0;
}
void disp(int * p, int n) {
 std::cout << std::endl;
 for (int i = 0; i < n; i++) std::cout << p[i] << " ";
 std::cout << std::endl;
}
int recUnit(int i, int j, int *a, int na, int *b, int nb) {
 if (i < na && j < nb) a[i] = b[j];
 else return i;
 return recUnit(i + 1, j + 1, a, na, b, nb);
}
void unit(int *a, int na, int *b, int nb, int *c, int nc) {
 int i;
 i = recUnit(0, 0, a, na, b, nb);
 recUnit(i, 0, a, na, c, nc);
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
766 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 22:24:32.63 ID:zGjt7Ia9
ちゃんと出来てるかこっちのほうがいいか
void unit2(int *a, int na, int *b, int nb, int *c, int nc) {
 int i, j;
 for (i = 0, j = 0; j < nb; i++, j++) if (i < na) a[i] = b[j];
 for (j = 0; j < nc; i++, j++) if (i < na) a[i] = c[j];
}
int main()
{
 int a[10], b[4] = { 0, 1, 2, 3 }, c[6] = { 4, 5, 6, 7, 8, 9 };
 init(a, 10); unit(a, 10, b, 4, c, 6); disp(a, 10);
 init(a, 10); unit2(a, 10, b, 4, c, 6); disp(a, 10);
 return 0;
}
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
767 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 22:31:18.83 ID:zGjt7Ia9
最適化されているのはループで
漸化式定義に忠実で書きやすいのが再帰だよ
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
768 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 22:33:05.45 ID:zGjt7Ia9
>>757
>>759
>>767
なあ、再帰関数好きな人いる? [転載禁止]©2ch.net
769 :NAS6 ◆n3AmnVhjwc []:2015/09/05(土) 22:47:45.27 ID:zGjt7Ia9
void recForFunc() { ; }
int recFor(int i, int n, int a) {
 if (n <= i) return i;
 recForFunc();
 return recFor(i + a, n, a);
}


std::cout << recFor(0, 10, 2) << std::endl;

for (i = 0; i < 10; i += 2) recForFunc();
std::cout << i << std::endl;

ループと再帰の違いは
スコープスタックを保存しているかしていないかだけ
次へ>>

※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。