前提・実現したいこと
フィボナッチ数列を動的計画法を用いて求めました。
動的計画法を用いるにはメモ用の配列を用意する必要があると思うのですが、
C#ではグローバル変数が使えないため、試行錯誤して力技で実装しました。
メモ用配列の用意の仕方は下記に記載しました。
メモ用配列の用意の仕方についてアドバイス等頂けないでしょうか??
メモ用数列の用意
- Main関数にて、メモ用数列をlist<int>として定義(変数名:memo)
- Main関数にて、for文を用いて全てに-1を代入
- fibo関数でもMain関数で定義したmemo配列を使用するため、refを用いて参照できるようにした
- fibo関数にて、memo配列にメモしながら返り値を計算
該当のソースコード
C#
1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace AtCoder 6{ 7 class Problem 8 { 9 static void Main() 10 { 11 // 何番目のフィボナッチ数列を求めたいか入力を受ける 12 var input = int.Parse(Console.ReadLine()); 13 // fibo(N)の答えをメモ化する配列を定義 14 var memo = new List<int> {}; 15 // メモ化用配列を-1で初期化する 16 for (int i = 0; i <= input; i++) 17 { 18 memo.Add(-1); 19 } 20 // n番目のフィボナッチ数列を出力 21 Console.WriteLine(fibo(input, ref memo)); 22 // 以下は確認用 23 var j = 0; 24 foreach (int num in memo) 25 { 26 Console.WriteLine("{0}番目: {1}", j, num); 27 j++; 28 } 29 } 30 31 // 再帰関数用メソッドの定義 32 static int fibo (int n, ref List<int> memo) 33 { 34 // 現在の進行状況を報告 35 Console.WriteLine("fibo({0})を呼び出しました", n); 36 37 // ベースケース 38 if (n == 0) return memo[0] = 0; 39 if (n == 1) return memo[1] = 1; 40 41 // メモをチェック 42 if (memo[n] != -1) return memo[n]; 43 44 // 再帰呼び出し 45 return memo[n] = fibo(n-1, ref memo) + fibo(n-2, ref memo); 46 } 47 } 48} 49
追記
データ専用のクラスを作成し、そのクラス内で再帰関数を呼び出すように修正しました。
アドバイスいただきありがとうございました。
以下に、修正したコードを添付します。
【修正版】ソースコード
C#
1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace AtCoder 6{ 7 class Problem 8 { 9 static void Main() 10 { 11 // 何番目までかを受け取る 12 var input = int.Parse(Console.ReadLine()); 13 14 // memo用listを作成し、-1で初期化する 15 var data = new Data(); 16 data.Memo = new List<int>(); 17 for (int i = 0; i <= input; i++) 18 { 19 data.Memo.Add(-1); 20 } 21 22 // n番目のフィボナッチ数列を出力 23 Console.WriteLine(data.fibo(input)); 24 25 // 以下は確認用 26 var j = 0; 27 foreach (int num in data.Memo) 28 { 29 Console.WriteLine("{0}番目: {1}", j, num); 30 j++; 31 } 32 } 33 } 34 35 class Data 36 { 37 public List<int> Memo {get; set;} // memo用のlist 38 39 public int fibo(int i) 40 { 41 // ベースケース 42 if (i == 0) return Memo[i] = 0; 43 if (i == 1) return Memo[i] = 1; 44 45 // memoをチェック 46 if (Memo[i] != -1) return Memo[i]; 47 48 // 再帰呼び出し 49 return Memo[i] = fibo(i - 1) + fibo(i - 2); 50 } 51 } 52}
回答2件
あなたの回答
tips
プレビュー