Excel精英培训网

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

[已解决]VBA实现和分拆为多个整数一共多少组

[复制链接]
发表于 2016-3-30 19:48 | 显示全部楼层 |阅读模式
VBA实现和分拆为多个整数一共多少组

把数字21拆成5个不相同整数

也就是说5个不相同正整数相加等于21,

用VBA输出一共有多少组


最佳答案
2016-3-30 20:54
不算重复的共10组
  1. Dim x, n%, s
  2. Sub Macro1()
  3. x = 11: n = 5: s = 0
  4. [a:a] = ""
  5. aa "", 0, 0, 0
  6. End Sub
  7. Sub aa(a, hj, t, cz)
  8. If t = n And hj = 21 Then
  9.     s = s + 1
  10.     Cells(s, 1) = Mid(a, 2)
  11. End If
  12. For i = 1 To x
  13.     If InStr("," & a & ",", "," & i & ",") = 0 And cz < i Then aa a & "," & i, hj + i, t + 1, i
  14. Next
  15. End Sub
复制代码
发表于 2016-3-30 20:05 | 显示全部楼层
  1. Sub 拆()
  2.     Dim s%, a%, b%, c%, d%, e%, arr(), x%
  3.     s = 21
  4.     For a = 1 To 21
  5.         For b = a + 1 To 21
  6.             For c = b + 1 To 21
  7.                 For d = c + 1 To 21
  8.                     e = 21 - a - b - c - d
  9.                     If e > d Then
  10.                         x = x + 1
  11.                         ReDim Preserve arr(1 To x)
  12.                         arr(x) = Array(a, b, c, d, e)
  13.                     End If
  14.                 Next d
  15.             Next c
  16.         Next b
  17.     Next a
  18.     MsgBox x
  19. End Sub
复制代码
回复

使用道具 举报

 楼主| 发表于 2016-3-30 20:23 | 显示全部楼层
wp8680 发表于 2016-3-30 20:05

你在搞什么,把这10组输出来
回复

使用道具 举报

发表于 2016-3-30 20:54 | 显示全部楼层    本楼为最佳答案   
不算重复的共10组
  1. Dim x, n%, s
  2. Sub Macro1()
  3. x = 11: n = 5: s = 0
  4. [a:a] = ""
  5. aa "", 0, 0, 0
  6. End Sub
  7. Sub aa(a, hj, t, cz)
  8. If t = n And hj = 21 Then
  9.     s = s + 1
  10.     Cells(s, 1) = Mid(a, 2)
  11. End If
  12. For i = 1 To x
  13.     If InStr("," & a & ",", "," & i & ",") = 0 And cz < i Then aa a & "," & i, hj + i, t + 1, i
  14. Next
  15. End Sub
复制代码

评分

参与人数 1 +9 收起 理由
vbyou127 + 9 来学习

查看全部评分

回复

使用道具 举报

发表于 2016-3-31 09:04 | 显示全部楼层
我这个才是通用、高效的,【求总和定值的组合解】的递归算法:
  1. Dim m&, n&, k&
  2. Sub test()
  3.     Dim h&, i&
  4.     h = 31 '目标总和 21 或 31
  5.     n = 6   '目标个数 5 或 6

  6.     m = h
  7.     For i = 1 To n - 1
  8.         m = m - i '计算得到m最大值范围 (前n-1个数为自然数序列时)
  9.     Next
  10.    
  11.     [a:a] = ""
  12.     k = 0: Call dg("", h, 0, 1)
  13.     MsgBox k
  14. End Sub

  15. Sub dg(s$, h&, j&, t&)
  16.     Dim i&
  17.     For i = j + 1 To m - n + t
  18.         If t < n Then
  19.             Call dg(s & "+" & i, h - i, i, t + 1) '个数t不满足时继续递归
  20.         Else '个数满足
  21.             If h = i Then k = k + 1: Cells(k, 1) = Mid(s & "+" & i, 2) '且总和满足时输出结果
  22.         End If
  23.     Next
  24. End Sub
复制代码
呵呵。楼主慢慢体会吧。

运算效率比dsmch的高多了。

评分

参与人数 1 +6 收起 理由
lichuanboy44 + 6 很给力

查看全部评分

回复

使用道具 举报

发表于 2016-3-31 09:11 | 显示全部楼层
本帖最后由 香川群子 于 2016-3-31 09:13 编辑

对于特定要求,递归过程还可以再缩减一步!提高效率。
  1. Dim m&, n&, k&
  2. Sub test()
  3.     Dim h&, i&
  4.     h = 31
  5.     n = 6
  6.     m = h
  7.     For i = 1 To n - 1
  8.         m = m - i
  9.     Next
  10.    
  11.     [a:a] = ""
  12.     k = 0: Call dg("", h, 0, 1)
  13.     MsgBox k
  14. End Sub
  15. Sub dg(s$, h&, j&, t&)
  16.     Dim i&
  17.     For i = j + 1 To m - n + t
  18.         If t < n - 1 Then
  19.             Call dg(s & "+" & i, h - i, i, t + 1)
  20.         Else
  21.             If h - i > i Then k = k + 1: Cells(k, 1) = Mid(s & "+" & i & "+" & h - i, 2)
  22.             '循环到n-1时计算出n的值=h-i 判断是否合理即可输出
  23.         End If
  24.     Next
  25. End Sub
复制代码
'循环到n-1时计算出n的值=h-i 判断是否合理即可输出,减少了很多循环。
从4368次减少至1365次。
回复

使用道具 举报

发表于 2016-3-31 09:19 | 显示全部楼层
这个Vbyou提高很快啊,从一开始的什么都不会到现在专攻算法啦?
回复

使用道具 举报

发表于 2016-3-31 09:21 | 显示全部楼层
grf1973 发表于 2016-3-31 09:19
这个Vbyou提高很快啊,从一开始的什么都不会到现在专攻算法啦?

对于特定要求,递归过程还可以再缩减一步!提高效率。
  1. Dim m&, n&, k&
  2. Sub test()
  3.     Dim h&, i&
  4.     h = 31
  5.     n = 6
  6.     m = h
  7.     For i = 1 To n - 1
  8.         m = m - i
  9.     Next
  10.    
  11.     [a:a] = ""
  12.     k = 0: Call dg("", h, 0, 1)
  13.     MsgBox k
  14. End Sub
  15. Sub dg(s$, h&, j&, t&)
  16.     Dim i&
  17.     For i = j + 1 To m - n + t
  18.         If t < n - 1 Then
  19.             Call dg(s & "+" & i, h - i, i, t + 1)
  20.         Else
  21.             If h - i > i Then k = k + 1: Cells(k, 1) = Mid(s & "+" & i & "+" & h - i, 2)
  22.             '循环到n-1时计算出n的值=h-i 判断是否合理即可输出
  23.         End If
  24.     Next
  25. End Sub
复制代码
'循环到n-1时计算出n的值=h-i 判断是否合理即可输出,减少了很多循环。

对于和=31、个数=6的计算次数从4368次减少至1365次。而dsmch的代码需运算65536次。
对于和=21、个数=5的计算次数从330减少至120次。而dsmch的代码需运算2048次。
回复

使用道具 举报

发表于 2016-3-31 09:23 | 显示全部楼层
grf1973 发表于 2016-3-31 09:19
这个Vbyou提高很快啊,从一开始的什么都不会到现在专攻算法啦?

他一直在出题目的吧。

题目的难度在不断提高。最初问的问题都是菜鸟操作,最近问的问题开始需要算法解题了。

很有趣。活跃了论坛。
回复

使用道具 举报

发表于 2016-3-31 12:01 | 显示全部楼层
本帖最后由 张雄友 于 2016-3-31 12:30 编辑
香川群子 发表于 2016-3-31 09:23
他一直在出题目的吧。

题目的难度在不断提高。最初问的问题都是菜鸟操作,最近问的问题开始需要算法解 ...

呵呵 ,美女厉害。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-19 12:50 , Processed in 0.297884 second(s), 11 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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