【问题标题】:Standard ML semifactorial using a reduce function使用 reduce 函数的标准 ML 半阶乘
【发布时间】:2013-11-21 12:53:30
【问题描述】:

我正在关注这个关于标准 ML 的教程:http://homepages.inf.ed.ac.uk/stg/NOTES/node2.html,我遇到了这个问题:

如果 n 为奇数,则正整数 n 的半阶乘为 1 × 3 × 5 × ... × n,如果 n 为偶数,则为 2 × 4 × 6 × ... × n。使用 reduce 函数定义计算半阶乘的 semifac 函数。

减少定义为:

fun reduce (g, e, m, n, f) =
    if m > n then e else g (reduce (g, e, m, n-1, f), f n);

我花了几个小时来解决这个问题,但找不到不需要更改 reduce 函数的令人满意的答案。如果将 reduce 重新定义为:

fun reduce' (g, e, m, n, f) = 
    if m > n then e else g (reduce'(g, e, m, n-2, f), f n);

最终解决方案为:

 fun semifactorial n = reduce'(fn (x,y) => x * y, 1, 1, n, fn x=>x);

我认为作者试图达到的目的是什么,但我不确定。有没有办法在不改变reduce定义的情况下解决这个问题?我在想有一些非常明显的功能方法可以做到这一点,但我看不出如何将减量减少 2 而不是 1(我的直觉说答案在于为 g 和 f 选择正确的函数 val)。

【问题讨论】:

    标签: functional-programming sml smlnj


    【解决方案1】:

    你很亲密。答案是选择正确的f。特别是,f 可以依赖于n 是关键。

    fun semifactorial n = reduce(fn (x,y) => x * y, 1, 1,
                                 n, fn x => if x mod 2 = n mod 2 then x else 1)
    

    应该可以。

    另外,更干净一点:

    fun foo n x = if (x + n) mod 2 = 0 then x else 1
    fun semifactorial n = reduce((op* ), 1, 1, n, foo n x)
    

    尽管如果您的 ML 实现不支持任意精度整数,则此表单确实有可能因 nx 的特别大的值而失败。

    【讨论】:

      【解决方案2】:

      您可以使用f 来决定是否乘以索引。只有当奇偶校验相同时才应该将它们相乘。

      fun sfact n = reduce(op*, 1, 1, n, fn k => if n mod 2 + k mod 2 = 1 then 1 else k);
      

      【讨论】:

      • 你们几乎同时回答了 - 抱歉,我不能同时接受这两个答案!
      猜你喜欢
      • 1970-01-01
      • 2014-11-26
      • 2020-12-17
      • 2015-10-06
      • 2017-05-09
      • 2019-05-30
      • 2016-01-19
      • 2021-02-07
      • 1970-01-01
      相关资源
      最近更新 更多