嵌套循环和函数式编程

时间:2017-10-19 06:47:12

标签: f#

请考虑一个C程序,给定xyzy + z * 2 = x,尽可能小y。粗略地说,我可以创建一个嵌套循环:

for(y = 0; y < x; ++ y){
    for(z = 0; z < x; ++z){
        if(y + 2 * z == x){
            printf("%d + 2 * %d = %d", y, z, x);
        }
    }
} 

我怎样才能在功能方式中翻译这种嵌套循环?这可行吗?是合理还是我只是误判了这种方法?到目前为止我最好的尝试:

let foo x =
    let rec aux (y, z, q) =
        match (y + z * 2) with
        r when r = q -> (y, z)
        |_      -> aux(y + 1, z + 1, q)  //How to check different values of z
    aux(0, 0, x)                         //for each value of y?

它无效,因为它只会递增yz。对于y的每个值,我如何检查z的不同值?

1 个答案:

答案 0 :(得分:4)

你必须在比赛中添加这些支票。

请在此处查看您的代码缺失的内容:

let foo x =
    let rec aux (y, z, q) =
        match (y + z * 2) with
        | r when r = q -> (y, z)
        | _ when y = q -> failwith "not found !"
        | _ when z = q -> aux (y + 1, 0, q)
        | _            -> aux (y, z + 1, q)
    aux (0, 0, x)

这是一种不同的方法,同样功能但没有递归:

let foo2 x =
    let s =
        {0 .. x} |> Seq.collect (fun y ->
            {0 .. x} |> Seq.collect (fun z -> 
                seq [y, z]))
    Seq.find (fun (y, z) -> y + z * 2 = x) s

在F#中可以使用seq表达式编写:

let foo3 x =
    let s = seq {
        for y in {0 .. x} do
            for z in {0 .. x} do
                yield (y, z)}
    Seq.find (fun (y, z) -> y + z * 2 = x) s

它类似于你原来的C程序。