前段时间从涛哥那学了一招——在递归里面使用Continuation 来避免大量的局部变量的使用,从而避免StackOverflow. 下面是一个小的例子:查找整数数组中的第K大的数:
在递归中使用Continuation来避免StackOverflow(查找第K大的数):
[<AutoOpen>] module Kmax type public Sort() = static member KMax(iArr : int array, kmax : int) = let iLen = iArr.Length match kmax with | small when small <= 0 -> failwith "too small" | larger when larger > iLen -> failwith "too large" | _ -> () let rec getMax iarr currMax contFun= match currMax with | 1 -> iarr |> Array.max | _ -> let max = iarr |> Array.max //delete the max item let restArr = let currMaxIndex = iarr |> Array.findIndex(fun x -> x = max) //get the sub array from 0 to currMaxIndex let newArrleft = Array.sub iarr 0 currMaxIndex //get the sub array form currMaxIndex+1 to end let newArrrigth = Array.sub iarr (currMaxIndex + 1) (iarr.Length - 1 - currMaxIndex) //concat these two array Array.append newArrleft newArrrigth let currMax = contFun(currMax - 1) getMax restArr currMax contFun getMax iArr kmax id
代码中的contFun是一个函数,在使用递归函数getMax时,给出相应的具体函数,本例中使用的是F#本身定义的操作函数:id,它的作用就相当于let customFun x = x, 也就是返回原参数的值。还是一样, 做个笔记~ :)。