13.递归实战技巧例 [例1] 递归(基础教程)(彭希仁) 这个贴子建议您仔细地多看几遍。 [例2]组合问题:列出n个数(1-n)中任选r个数的所有组合。 分析:设定用数组arr来保存所有组合结果(每一个结果为用空格隔开的数字,如:“1 2 3 4”),变量q来记录组合个数,根据已经知道的数学知识,q=n!/(r!*(n-r)!),这样我们就不多次使用redim arr了,计算阶乘的函数我们也已经有了。先来分析递归过程,假定过程名为cmb(n,r),两个参数为n、r,“基状态”有两个: (1)当r=1时,可以将1-n分别写入数组。 (2)当n=r时,可以直接将结果(1 2 3…n)写入数组。 “递归部分”: 考虑从1-n中选r的数,可以分解成两种情况: (1)当这r个数中有n时,此时可以先求出cmb(n-1,r-1),然后在cmb(n-1,r-1)的结果中把n加上去就是r个数了。这样的话,我们可以增加一个参数s,传递要求包含的数字(为字符型),如果没有需要传递的参数s,可以传递空串。 (2)当这r个数中没有n时,此时的结果就是cmb(n-1,r)。 通过分解成这两种情况,降低复杂度的目的就达到了。这样递归代码也就出来了: Dim arr, q Sub main() Dim n%, r% n = 8 r = 3 q = 0 ReDim arr(1 To nx(n) / nx(r) / nx(n - r)) cmb n, r, "" Columns("A").ClearContents [a1].Resize(q, 1) = Application.Transpose(arr) End Sub Sub cmb(ByVal n As Integer, ByVal r As Integer, ByVal s As String) Dim i% If r = 1 Then For i = 1 To n q = q + 1 arr(q) = i & " " & s Next i Exit Sub ElseIf n = r Then q = q + 1 For i = 1 To n arr(q) = arr(q) & i & " " Next i arr(q) = arr(q) & s Exit Sub End If cmb n - 1, r, s cmb n - 1, r - 1, n & " " & s End Sub Function nx(n) Dim i% nx = 1 For i = 2 To n nx = nx * i Next i End Function [例3]列出指定文件夹及其子文件夹下的所有文件。 分析: (1)“出口”条件: 当文件夹下没有子文件夹,列出该文件夹下的文件即可。 (2)“递归部分”降阶: 以该文件夹的子文件夹做参数,再次引发递归。 代码见: http://club.excelhome.net/viewthread.php?tid=206228 [例4]…… 事不过三,呵呵,开个玩笑。以后再慢慢补充吧,也欢迎大家把好的代码拿出来分享。
[此贴子已经被作者于2007-2-7 22:12:14编辑过] |