ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 香川群子

[分享] 香川组合的递归代码

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-11 16:24 | 显示全部楼层
本帖已被收录到知识树中,索引项:递归
本帖最后由 香川群子 于 2012-7-11 16:35 编辑

  1. Public cnt

  2. Sub mySerch()
  3.     ActiveCell.CurrentRegion.Interior.ColorIndex = 0
  4.     arr = [a1:z26]
  5.     Randomize
  6.     For i = 2 To 25
  7.         For j = 2 To 25
  8.             If Rnd() > 0.5 Then arr(i, j) = 1 Else arr(i, j) = 0
  9.         Next
  10.     Next
  11.     [a1:z26] = arr
  12.     '以上是每次重新随机生成迷宫
  13.    
  14.    t = ActiveCell
  15.    cnt = 0
  16.      Call schdg(ActiveCell.Row, ActiveCell.Column, t) '调用递归过程
  17.    ActiveCell.Interior.ColorIndex = 4
  18. End Sub

  19. '下面是递归过程
  20. Sub schdg(i, j, t)
  21.     If Cells(i - 1, j) = t And Cells(i - 1, j).Interior.ColorIndex <> 3 Then
  22.         Cells(i - 1, j).Interior.ColorIndex = 3: cnt = cnt + 1: Cells(i - 1, j) = cnt
  23.         Call schdg(i - 1, j, t)
  24.     End If
  25.    
  26.     If Cells(i, j + 1) = t And Cells(i, j + 1).Interior.ColorIndex <> 3 Then
  27.         Cells(i, j + 1).Interior.ColorIndex = 3: cnt = cnt + 1: Cells(i, j + 1) = cnt
  28.         Call schdg(i, j + 1, t)
  29.     End If
  30.    
  31.     If Cells(i + 1, j) = t And Cells(i + 1, j).Interior.ColorIndex <> 3 Then
  32.         Cells(i + 1, j).Interior.ColorIndex = 3: cnt = cnt + 1: Cells(i + 1, j) = cnt
  33.         Call schdg(i + 1, j, t)
  34.     End If
  35.    
  36.     If Cells(i, j - 1) = t And Cells(i, j - 1).Interior.ColorIndex <> 3 Then
  37.         Cells(i, j - 1).Interior.ColorIndex = 3: cnt = cnt + 1: Cells(i, j - 1) = cnt
  38.         Call schdg(i, j - 1, t)
  39.     End If
  40.    
  41.    
  42. End Sub
复制代码
dg.zip (23 KB, 下载次数: 147)

TA的精华主题

TA的得分主题

发表于 2012-7-11 16:51 | 显示全部楼层
香川群子 发表于 2012-7-11 11:34
AVEL,给你出个简单的题目:

写一个简单的递归过程,计算返回自然数1-N的总和 (即,1+2+3+……+N 求和) ...

Option Explicit
Dim jg As Double
Sub dg()
    l 100
    jg = 0
End Sub
Sub l(i As Integer)
    If i = 0 Then Exit Sub
    jg = jg + i
    Debug.Print jg
    l i - 1
End Sub
老师帮忙看看。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-11 17:11 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 香川群子 于 2012-7-11 17:36 编辑
AVEL 发表于 2012-7-11 16:51
Option Explicit
Dim jg As Double
Sub dg()


正确。

要点都有了。

这样写,看起来清楚一点。
Dim jg As Double '定义公共变量以便传递结果

Sub dg()
    jg = 0 '结果变量初始化
    Call l(100) '输入参数,调用递归过程
    MsgBox jg '输出结果
End Sub

Sub l(i%)
    If i = 0 Then Exit Sub  '退出递归的条件
    jg = jg + i '本次递归计算处理
    Call l(i - 1) '输入新的参数,进入下一阶层的递归
End Sub


呵呵。这样不是很好么。

递归过程写成一行也可以:
Sub l(i%)
    If i > 0 Then jg = jg + i: Call l(i - 1)
End Sub

不过,对于初学者来说,写成3行的话,递归过程就很容易看明白了。


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-11 17:27 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 香川群子 于 2012-7-11 17:27 编辑

下面这样,也是一种写法:

Public jg  '定义公共变量传递结果

Sub mySum()
    Call sumdg(0, 4800) '直接输入参数调用递归(并已对结果初始化)
    MsgBox jg '输出结果
End Sub

Sub sumdg(s, n%)
    If n = 0 Then jg = s: Exit Sub '满足条件时退出,并传递最终结果
    Call sumdg(s + n, n - 1) ''直接计算并输入新参数,进入下一阶层的递归调用
End Sub


不过,比较下来,还是23楼代码效率更高。

但多一种写法,也是一种体验。

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-7-11 17:31 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
如果直接使用递归函数,则更简单。但是内存利用的效率稍低一些。

Sub mySum2()
    MsgBox s(4370)
End Sub

Function s(n%)
    If n = 1 Then s = 1 Else s = n + s(n - 1)
End Function

呵呵。
递归很有趣吧。

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2012-7-25 14:04 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-12 17:07 | 显示全部楼层
递归方法计算不重复组合结果的代码:
  1. Public sj, jg(), m, n, k
  2. Sub 不重复组合递归()
  3.     m = [a1].End(4).Row: n = [b1]
  4.     sj0 = [a1].Resize(m): [a1].Resize(m).Sort [a1], 1, , , 2
  5.     sj = [a1].Resize(m)
  6.     [a1].Resize(m) = sj0
  7.     AC = WorksheetFunction.Combin(m, n)
  8.     If AC > 65536 Then ReDim jg(65535, n) Else ReDim jg(AC, n)
  9.     k = 1
  10.     Call bcfzhdg("", 0, 0)
  11.     [d1].CurrentRegion = "": [d1].Resize(k, n + 1) = jg
  12. End Sub
  13. Sub bcfzhdg(s, i, t%)
  14.     If t = n Then
  15.         p = Split(s, ",")
  16.         For j = 1 To n
  17.             jg(0, j) = p(j)
  18.             jg(k, j) = p(j)
  19.         Next
  20.         jg(k, 0) = Mid(s, 2): k = k + 1: Exit Sub
  21.     End If
  22.     For j = i + 1 To m
  23.         If CStr(sj(j, 1)) <> jg(0, t + 1) Then
  24.             If t < n - 1 Then jg(0, t + 2) = ""
  25.             Call bcfzhdg(s & "," & sj(j, 1), j, t + 1)
  26.         End If
  27.     Next j
  28. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-12 17:11 | 显示全部楼层
不重复排列结果的递归代码相当有难度,一下子搞不出来。
(for……next的循环代码是有的,就是太复杂了)

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-8-12 17:17 | 显示全部楼层
所谓组合求和,就是m个数中,任取1-n个组合并相加,要求总和等于固定的目标值。
求所有符合条件的组合解。
  1. Public sj, jg(), jg2(), m, n, k, h, cnt
  2. Sub 组合求和递归()
  3.     m = [a1].End(4).Row: h = [b1]
  4.     sj0 = [a1].Resize(m): [a1].Resize(m).Sort [a1], 1, , , 2
  5.     sj = [a1].Resize(m)
  6.     [a1].Resize(m) = sj0
  7.     ReDim jg(65535, 0): k = 0
  8.     'ReDim jg2(65535, 0): cnt = 0
  9.     Call hdg("", 0, 0, 0)
  10.     [d1].CurrentRegion = "": [d1].Resize(k) = jg: [b2] = k
  11.     '[e1].Resize(cnt) = jg2: [b3] = cnt
  12. End Sub
  13. Sub hdg(s, r, i, t%)
  14.     'jg2(cnt, 0) = "=" & Mid(s, 2): cnt = cnt + 1
  15.     If r = h Then jg(k, 0) = s: k = k + 1: Exit Sub
  16.     For j = i + 1 To m
  17.         If r + sj(j, 1) > h Then Exit For
  18.         Call hdg(s & "+" & sj(j, 1), r + sj(j, 1), j, t + 1)
  19.     Next j
  20. End Sub
复制代码
例如:1-10的10个自然数中,求总和=8的各种组合

结果如下:
+1+2+5
+1+3+4
+1+7
+2+6
+3+5
8

TA的精华主题

TA的得分主题

发表于 2012-8-12 17:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
先留记号,等会来学,谢谢
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-17 00:52 , Processed in 0.034790 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表