関数型パラダイムでの動的プログラミング

ルイス・プリンゲ:

私はProject Eulerの問題31を見ています。これは、1p、2p、5p、10p、20p、50p、£1(100p)、£の任意の数のコインを使用して£2を作成する方法はいくつあるかを尋ねます。 2(200p)。

Scalaにあるような再帰的な解決策があります(Pavel Fatinの功績)

def f(ms: List[Int], n: Int): Int = ms match {
  case h :: t =>
    if (h > n) 0 else if (n == h) 1 else f(ms, n - h) + f(t, n)
  case _ => 0
} 
val r = f(List(1, 2, 5, 10, 20, 50, 100, 200), 200)

また、十分に高速で実行されますが、比較的効率が悪く、f関数を約560万回呼び出します。

動的にプログラムされたJavaで他の誰かの解決策を見ました(ポルトガルのwizemanへのクレジット)

final static int TOTAL = 200;

public static void main(String[] args) {
    int[] coins = {1, 2, 5, 10, 20, 50, 100, 200};
    int[] ways = new int[TOTAL + 1];
    ways[0] = 1;

    for (int coin : coins) {
        for (int j = coin; j <= TOTAL; j++) {
            ways[j] += ways[j - coin];
        }
    }

    System.out.println("Result: " + ways[TOTAL]);
}

これははるかに効率的であり、内部ループを1220回しか通過しません。

Arrayオブジェクトを使用してこれを多かれ少なかれ逐語的にScalaに変換することはできますが、不変のデータ構造を使用してこれを行う慣用的な機能的な方法はありますか?

私は、Listおそらく間違った方法でそれに近づいていると判断する前に、再帰的に更新しようと試みて行き詰まりました。

ダニエルC.ソブラル:

データのリストの一部が前の要素に基づいて計算されるときはいつでも、私はStream再帰を考えます。残念ながら、そのような再帰はメソッド定義や関数の内部では発生しないため、関数をクラスに変換して機能させる必要がありました。

class IterationForCoin(stream: Stream[Int], coin: Int) {
  val (lower, higher) = stream splitAt coin
  val next: Stream[Int] = lower #::: (higher zip next map { case (a, b) => a + b })
}
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
val result = coins.foldLeft(1 #:: Stream.fill(200)(0)) { (stream, coin) =>
  new IterationForCoin(stream, coin).next
} last

定義lowerhigher必要はありません-私は簡単に置き換えることができstream take coinそしてstream drop coinこのように、私はそれが少し明確に(そしてより効率的)だと思います。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

関数型プログラミングの原則と関数型プログラミングのパラダイム?

分類Dev

関数型プログラミングパラダイムで2つの関数を一緒にマッピングする

分類Dev

他のプログラミングパラダイムの後に関数型プログラミングを学ぶ

分類Dev

関数型プログラミングの演習(ラムダ関数)

分類Dev

Javaと関数型プログラミングパラダイム - どのように私は私の配列は不変作るのですか

分類Dev

パイプラインの関数型プログラミングとPythonパンダデータフレーム

分類Dev

JavaScriptでの関数型プログラミングスタイルのパターンマッチング

分類Dev

Javaでの関数型プログラミング

分類Dev

Javaでの関数型プログラミング

分類Dev

OOP言語での関数型プログラミング

分類Dev

Androidでの純粋関数型プログラミング

分類Dev

JavaScriptでの関数型プログラミング

分類Dev

JSでの関数型プログラミング

分類Dev

Haskellでの総和-関数型プログラミング

分類Dev

Scalaでの関数型プログラミング

分類Dev

関数型プログラミングは一種の宣言型プログラミングですか?

分類Dev

マップ、ラムダ、関数型プログラミングのワークフローを使用したPythonでの配列のマッピング

分類Dev

関数型プログラミング:プロパティの合計

分類Dev

kotlinでの関数型プログラミング-関数の割り当て

分類Dev

配列内のJavascript関数型プログラミングと動的値

分類Dev

関数型プログラミングのパフォーマンス

分類Dev

関数型ヘッダーなしでコンパイルするC ++プログラム

分類Dev

ストリームの用途関数型プログラミング

分類Dev

関数型プログラミングのvsマップ

分類Dev

関数型プログラミングのカウンター

分類Dev

Javascriptの関数型プログラミングの戻り値

分類Dev

ggplotで関数型プログラミングを使用する

分類Dev

n個のアイテムのJS関数型プログラミングが入力されます

分類Dev

関数型プログラミングの学習

Related 関連記事

  1. 1

    関数型プログラミングの原則と関数型プログラミングのパラダイム?

  2. 2

    関数型プログラミングパラダイムで2つの関数を一緒にマッピングする

  3. 3

    他のプログラミングパラダイムの後に関数型プログラミングを学ぶ

  4. 4

    関数型プログラミングの演習(ラムダ関数)

  5. 5

    Javaと関数型プログラミングパラダイム - どのように私は私の配列は不変作るのですか

  6. 6

    パイプラインの関数型プログラミングとPythonパンダデータフレーム

  7. 7

    JavaScriptでの関数型プログラミングスタイルのパターンマッチング

  8. 8

    Javaでの関数型プログラミング

  9. 9

    Javaでの関数型プログラミング

  10. 10

    OOP言語での関数型プログラミング

  11. 11

    Androidでの純粋関数型プログラミング

  12. 12

    JavaScriptでの関数型プログラミング

  13. 13

    JSでの関数型プログラミング

  14. 14

    Haskellでの総和-関数型プログラミング

  15. 15

    Scalaでの関数型プログラミング

  16. 16

    関数型プログラミングは一種の宣言型プログラミングですか?

  17. 17

    マップ、ラムダ、関数型プログラミングのワークフローを使用したPythonでの配列のマッピング

  18. 18

    関数型プログラミング:プロパティの合計

  19. 19

    kotlinでの関数型プログラミング-関数の割り当て

  20. 20

    配列内のJavascript関数型プログラミングと動的値

  21. 21

    関数型プログラミングのパフォーマンス

  22. 22

    関数型ヘッダーなしでコンパイルするC ++プログラム

  23. 23

    ストリームの用途関数型プログラミング

  24. 24

    関数型プログラミングのvsマップ

  25. 25

    関数型プログラミングのカウンター

  26. 26

    Javascriptの関数型プログラミングの戻り値

  27. 27

    ggplotで関数型プログラミングを使用する

  28. 28

    n個のアイテムのJS関数型プログラミングが入力されます

  29. 29

    関数型プログラミングの学習

ホットタグ

アーカイブ