请考虑一个 C 程序,在给定的情况下x,它将返回y并且z使得y + 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我怎么能以功能方式翻译这种嵌套循环?可行吗?这是合理的还是我只是误判了这种方法?到目前为止我最好的尝试:
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?
Run Code Online (Sandbox Code Playgroud)
它不会工作,因为它只会增加y和z。对于每个 y 值,如何检查 z 的不同值?
您必须在比赛中添加这些检查。
在这里查看您缺少的代码:
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)
Run Code Online (Sandbox Code Playgroud)
这是一种不同的方法,功能相同但没有递归:
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
Run Code Online (Sandbox Code Playgroud)
在 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
Run Code Online (Sandbox Code Playgroud)
它类似于您原来的 C 程序。