Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 4537|回复: 10

[已解决]求组合

[复制链接]
发表于 2012-5-14 18:11 | 显示全部楼层 |阅读模式
用11个A字母组合成2个A字母的组合,3个A字母的组合,到11个A字母的组合,A与A是用"+" 或 "-" 相连例;
A+A
A-A
A+A+A
A+A-A
A-A+A
A-A-A  等等到第11位的组合,再把末位是 "-"相连的组合去掉(例A-A,  A+A-A,  A-A-A,等)  
   直接给结果也行
最佳答案
2012-11-7 13:11
用递归方法写了个代码……过程中重复项太多,最后用字典方法排除重复做好了。

结果正确,但代码冗余太多。

可以考虑用循环做,估计代码效率会高一点。

excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2012-5-14 18:26 | 显示全部楼层
回复

使用道具 举报

 楼主| 发表于 2012-5-14 18:31 | 显示全部楼层
那么的帅 发表于 2012-5-14 18:26
结果显示在哪里?

放在工作表里就可以
回复

使用道具 举报

 楼主| 发表于 2012-5-14 19:00 | 显示全部楼层
zhaongxa 发表于 2012-5-14 18:31
放在工作表里就可以

自己顶一下在线等
回复

使用道具 举报

发表于 2012-11-7 13:11 | 显示全部楼层    本楼为最佳答案   
用递归方法写了个代码……过程中重复项太多,最后用字典方法排除重复做好了。

结果正确,但代码冗余太多。

可以考虑用循环做,估计代码效率会高一点。

A A.zip

24.8 KB, 下载次数: 11

回复

使用道具 举报

发表于 2012-11-7 13:14 | 显示全部楼层

  1. Dim d, m%
  2. Sub kagawa()
  3.     m = [a1] 'A1单元格中写入要排列的字母A的个数。
  4.     Set d = CreateObject("Scripting.Dictionary")
  5.     Call dgH("+", "A+A", 0, 0)
  6.     MsgBox d.Count & vbCr & Format(Timer - tms, "0.000s")

  7.     '以上计算完毕,下面是输出结果到工作表
  8.     [c:h] = ""
  9.     [c1].Resize(d.Count) = Application.Transpose(d.items)
  10.     [d1].Resize(d.Count) = Application.Transpose(d.keys)
  11.     [c1].CurrentRegion.Sort [c1], 1, [d1], , 1, , 2
  12. End Sub
  13. Sub dgH(r$, s$, i%, t%) '递归计算
  14.     Dim j%
  15.     If t > m - 2 Then Exit Sub
  16.     d(s) = t + 2
  17.    
  18.     For j = i + 1 To m - 2
  19.         Call dgH("+" & r, "A+" & s, j, t + 1)
  20.         Call dgH("-" & r, "A-" & s, j, t + 1)
  21.     Next j
  22.    
  23. End Sub
复制代码
回复

使用道具 举报

发表于 2012-11-7 16:29 | 显示全部楼层
香川群子 发表于 2012-11-7 13:11
用递归方法写了个代码……过程中重复项太多,最后用字典方法排除重复做好了。

结果正确,但代码冗余太多 ...

估计楼主忘记结贴了。
群子老师的贴超有学习价值,希望常来转转啊{:021:}
回复

使用道具 举报

发表于 2012-11-7 16:48 | 显示全部楼层
膜拜。
回复

使用道具 举报

发表于 2012-11-7 21:16 | 显示全部楼层
本帖最后由 wcymiss 于 2012-11-7 21:29 编辑

写个不用递归不用字典的:
  1. Sub 组合()
  2. '按A的个数分组
  3. 'A的个数为2时组内元素为1个,值为"A+A"
  4. 'A的个数为3时,把上组内的元素前面分别添加"A+"和"A-",组成2个元素,为"A+A+A"和"A-A+A"
  5. 'A的个数为4时,把上组内的元素前面分别添加"A+"和"A-",组成2*2个元素
  6.     '为"A+A+A+A"、"A+A-A+A"、"A-A+A+A"、"A-A-A+A"
  7. 'A的个数为4时,把上组内的元素前面分别添加"A+"和"A-",组成2*4个元素
  8. '……
  9. 'A的个数为n时,把上组内元素前面分别添加"A+"和"A-",组成2^(n-2)个元素
  10.     Dim p() As String, x As Integer, i As Integer, j As Integer
  11.     Dim m As Integer, n As Integer, t
  12.     t = Timer
  13.     n = [a1].Value
  14.     ReDim p(1 To 2 ^ (n - 1) - 1, 1 To 1)
  15.     x = 1 '组内元素个数
  16.     m = 1 '组内最后元素在总组合的位置
  17.     p(1, 1) = "A+A" 'A的个数为2的一组,直接赋值
  18.     For i = 3 To n 'A的个数从3到n
  19.         For j = 1 To x '上组元素有x个,本组起始位置为m+1
  20.             p(m + j, 1) = "A+" & p(m - j + 1, 1)
  21.             p(m + j + x, 1) = "A-" & p(m - j + 1, 1)
  22.         Next
  23.         x = x * 2 '本组元素个数
  24.         m = m + x '本组最后位置
  25.     Next
  26.     MsgBox Timer - t
  27.     Range("e:e").ClearContents
  28.     Range("e1").Resize(UBound(p), 1) = p
  29. End Sub
复制代码
回复

使用道具 举报

发表于 2012-11-7 22:48 | 显示全部楼层
还是用递归。

递归-1,用字典方法记录。

递归-2,用数组方法记录,并能返回+-符号结果。


过程中已经排除了重复,效率有所提高。

不过,和9楼直接数组循环方式比,还是慢了不少……这个是递归的短板。
  1. Dim jg(), d, m%, k&
  2. Sub kagawa1()
  3.     tms = Timer
  4.     m = [a1]
  5.     [c:d] = ""
  6.    
  7.     Set d = CreateObject("Scripting.Dictionary")
  8.    
  9.     Call dgH1("A+A", 0, 0)
  10.    
  11.     [c1].Resize(d.Count) = Application.Transpose(d.items)
  12.     [d1].Resize(d.Count) = Application.Transpose(d.keys)
  13.     [c1].CurrentRegion.Sort [c1], 1, [d1], , 1, , 2
  14.     MsgBox "字典方法结果: " & d.Count & vbCr & Format(Timer - tms, "0.000s")
  15.    
  16. End Sub
  17. Sub dgH1(s$, i%, t%)
  18.     Dim j%
  19.    
  20.     d(s) = t + 2
  21.    
  22.     For j = i + 1 To m - 2
  23.         If j <= t + 1 Then Call dgH1("A+" & s, j, t + 1)
  24.         If j <= t + 1 Then Call dgH1("A-" & s, j, t + 1)
  25.     Next j
  26.    
  27. End Sub
  28. Sub kagawa2()
  29.     tms = Timer
  30.     m = [a1]
  31.     [f:h] = ""
  32.    
  33.     ReDim jg(2 ^ (m - 1) - 1, 2)
  34.    
  35.     k = 0
  36.    
  37.     Call dgH2("+", "A+A", 0, 0)
  38.    
  39.    
  40.     [f1].Resize(k, 3) = jg
  41.     [f1].CurrentRegion.Sort [f1], 1, [h1], , 1, , 2
  42.     MsgBox "数组记录递归方法结果: " & k & vbCr & Format(Timer - tms, "0.000s")
  43.    
  44. End Sub
  45. Sub dgH2(r$, s$, i%, t%)
  46.     Dim j%
  47.    
  48.     jg(k, 0) = t + 2: jg(k, 1) = r: jg(k, 2) = s: k = k + 1
  49.    
  50.     For j = i + 1 To m - 2
  51.         If j <= t + 1 Then Call dgH2("+" & r, "A+" & s, j, t + 1)
  52.         If j <= t + 1 Then Call dgH2("-" & r, "A-" & s, j, t + 1)
  53.     Next j
  54.    
  55. End Sub
复制代码

AA.rar

39.46 KB, 下载次数: 1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-20 19:49 , Processed in 0.311659 second(s), 8 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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