【问题标题】:Multiplying two numbers by successive sums in F#在 F# 中将两个数字乘以连续的和
【发布时间】:2015-05-07 22:51:53
【问题描述】:

将 m 和 n 作为整数,我可以将它们乘以连续的和,如下所示:

    m * n = m + m + m + ... + m (n times) 

那么,让我们考虑下面的伪代码:

    m = ... (first number)
    n = ... (second number)

    Result = 0;
    while (n > 0)
    {
        Result = Result + m;
        n = n - 1;
    }

知道变量是不可变的,我如何在 F# 中实现这个算法? 以另一种方式提出问题,如何在连续迭代中更新变量 Resultn

有人可以用 F# 编写这个算法吗?

谢谢

脚注:我开始学习 F#,我对函数式编程完全感到困惑。

【问题讨论】:

  • Array.create n m |> Array.sum

标签: f# functional-programming immutability


【解决方案1】:

您可以使用 Seq(像 Haskell 中的惰性列表 / 像 C# 中的 IEnumerable 一样)和管道运算符:

let mult n (m:int) =
    Seq.initInfinite (fun _ -> m)
    |> Seq.take n
    |> Seq.sum

【讨论】:

    【解决方案2】:

    首先,你可以在 F# 中使用可变变量,所以你的算法可以这样写:

    let multiply1 m n =
        let mutable result = 0
        for i = 1 to n do
            result <- result + m
        result
    

    但如果你想用函数式的方式做更多的事情,你会使用递归。在这种情况下,累积结果的内部函数:

    let multiply2 m n =
        let rec loop x acc =
            if x = 0 then acc
            else loop (x - 1) (acc + m)
        loop n 0
    

    multiply2 函数使用称为loop 的内部递归函数,该函数将乘法的结果累加到acc 参数中。所以循环调用自己n 次,并每次将m 添加到累加器中。一旦x 达到零,就会返回这个结果。

    从技术上讲,您也可以编写不带累加器参数的代码:

    let multiply3 m n =
        let rec loop x =
            if x = 0 then 0
            else m + loop (x - 1)
        loop n
    

    也许对于初学者来说这段代码更容易理解,但应该避免,因为它不使用tail recursion,这会导致问题。例如,这将导致 StackOverflowException:

    multiply3 5 1000000 // This will cause a StackOverflowException.
    |> printfn "Result: %d"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-12
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      相关资源
      最近更新 更多