ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 1500|回复: 6

[原创] 递归学习之--凑数的通用框架

[复制链接]

TA的精华主题

TA的得分主题

发表于 2020-1-21 16:47 | 显示全部楼层 |阅读模式
  1. Option Explicit

  2. Dim arrResult  As Variant



  3. Sub Test()
  4.     Dim arr As Variant, brr As Variant, strMsg As String
  5.    
  6.     ReDim arrResult(0) As String
  7.    
  8.     arr = Array(12, 34, 56, 7, 9, 0.9, 3456, 789, 234.66)
  9.    
  10.     If CheckValHasOK(arr, 830.9, brr) = True Then
  11.         arr = ""
  12.         If MakeUpNumber(brr, 1, 0, 830.9, arr, True) = True Then
  13.             MsgBox "已完成,共有组合:" & UBound(arrResult) & "组"
  14.             strMsg = Join(arrResult, vbCrLf)
  15.             MsgBox strMsg
  16.         Else
  17.             MsgBox "没有合适的数字!"
  18.         End If
  19.         
  20.     Else
  21.         MsgBox "现有数字不满足凑数条件!"
  22.     End If
  23. End Sub

  24. '凑数
  25. Function MakeUpNumber(arrList As Variant, lngStartID As Long, dblCur As Double, dblSum As Double, dblResult As Variant, Optional blGetAll As Boolean = True) As Boolean
  26.     Dim lngID As Long, lngCurID As Long
  27.     Dim dblCur_temp As Double, arrReturn As Variant
  28.     Dim blIsOk As Boolean
  29.    
  30.     lngCurID = lngStartID
  31.     arrReturn = dblResult
  32.    
  33.     If dblCur = dblSum Then
  34.         PushResultToArr arrReturn, arrResult, dblSum
  35.         MakeUpNumber = True
  36.         Exit Function
  37.     ElseIf dblCur < dblSum Then
  38.         If IsArray(arrReturn) Then
  39.             lngID = UBound(arrReturn) + 1
  40.             ReDim Preserve arrReturn(1 To lngID) As Double
  41.         Else
  42.             lngID = 1
  43.             ReDim arrReturn(1 To lngID) As Double
  44.         End If
  45.     Else
  46.         MakeUpNumber = False
  47.         Exit Function
  48.     End If
  49.    
  50.    
  51.     If lngCurID > UBound(arrList) Then
  52.         MakeUpNumber = False
  53.         Exit Function
  54.     End If
  55.    
  56.     For lngID = lngStartID To UBound(arrList)
  57.         If blIsOk And Not blGetAll Then Exit For
  58.         dblCur_temp = dblCur + arrList(lngID)
  59.         arrReturn(UBound(arrReturn)) = arrList(lngID)
  60.         blIsOk = blIsOk Or MakeUpNumber(arrList, lngID + 1, dblCur_temp, dblSum, arrReturn, blGetAll)
  61.     Next
  62.    
  63.     MakeUpNumber = blIsOk
  64. End Function

  65. '是否可以凑数
  66. Function CheckValHasOK(arr As Variant, dblSum As Double, arrResult As Variant) As Boolean
  67.     Dim lngID As Long, lngCur As Long
  68.     Dim lngStart As Long, lngEnd As Long, dblTemp As Double
  69.    
  70.     QuickSort arr, LBound(arr), UBound(arr), False '原始数组降序
  71.     lngStart = -1
  72.     lngEnd = UBound(arr)
  73.    
  74.     For lngID = LBound(arr) To UBound(arr)
  75.         If arr(lngID) <= dblSum Then
  76.             lngStart = lngID
  77.             Exit For
  78.         End If
  79.     Next
  80.    
  81.     If lngStart = -1 Then
  82.         CheckValHasOK = False
  83.     End If
  84.    
  85.     ReDim arrResult(1 To lngEnd - lngStart + 1) As Double
  86.     lngCur = 1: dblTemp = 0
  87.     For lngID = lngStart To lngEnd
  88.         arrResult(lngCur) = arr(lngID)
  89.         dblTemp = dblTemp + arrResult(lngCur)
  90.         lngCur = lngCur + 1
  91.     Next
  92.    
  93.     If dblTemp < dblSum Then
  94.         CheckValHasOK = False
  95.     Else
  96.         CheckValHasOK = True
  97.     End If
  98. End Function

  99. '结果输出
  100. Function PushResultToArr(arrSource As Variant, ByRef arrResult As Variant, dblSum As Double)
  101.     Dim strTemp As String
  102.     Dim lngID As Long
  103.    
  104.     For lngID = LBound(arrSource) To UBound(arrSource)
  105.         strTemp = IIf(strTemp = "", arrSource(lngID), strTemp & "+" & arrSource(lngID))
  106.     Next
  107.    
  108.     lngID = UBound(arrResult) + 1
  109.     ReDim Preserve arrResult(0 To lngID)
  110.     arrResult(lngID) = strTemp & "=" & dblSum
  111. End Function

  112. '快速排序
  113. Function QuickSort(arr As Variant, lngStartID As Long, lngEndID As Long, Optional blIsASC As Boolean = True)
  114.     Dim varCheck As Variant
  115.     Dim lngS As Long, lngE As Long
  116.    
  117.     If Not IsArray(arr) Then Exit Function
  118.     If lngStartID >= lngEndID Then Exit Function
  119.    
  120.     varCheck = arr(lngStartID)
  121.     lngS = lngStartID: lngE = lngEndID
  122.    
  123.     While lngS <> lngE
  124.         If blIsASC Then
  125.             '升序
  126.             While lngE > lngS And arr(lngE) >= varCheck
  127.                 lngE = lngE - 1
  128.             Wend
  129.             SwapArr arr, lngS, lngE
  130.             While lngS < lngE And arr(lngS) <= varCheck
  131.                 lngS = lngS + 1
  132.             Wend
  133.             SwapArr arr, lngS, lngE
  134.         Else
  135.             '降序
  136.             While lngE > lngS And arr(lngE) <= varCheck
  137.                 lngE = lngE - 1
  138.             Wend
  139.             SwapArr arr, lngS, lngE
  140.             While lngS < lngE And arr(lngS) >= varCheck
  141.                 lngS = lngS + 1
  142.             Wend
  143.             SwapArr arr, lngS, lngE
  144.         End If
  145.     Wend
  146.    
  147.     QuickSort arr, lngStartID, lngS - 1, blIsASC
  148.     QuickSort arr, lngS + 1, lngEndID, blIsASC
  149. End Function

  150. '数组交换
  151. Private Function SwapArr(arr As Variant, lngA As Long, lngB As Long)
  152.     Dim varTemp As Variant
  153.     varTemp = arr(lngA)
  154.     arr(lngA) = arr(lngB)
  155.     arr(lngB) = varTemp
  156. End Function

复制代码


评分

6

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-1-21 16:53 | 显示全部楼层
老师威武!抢个沙发先,好好学习学习。

TA的精华主题

TA的得分主题

发表于 2020-1-21 17:01 | 显示全部楼层
最好上传个带实例的附件,方便菜鸟们直观地学习。

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-1-21 17:24 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
WYS67 发表于 2020-1-21 17:01
最好上传个带实例的附件,方便菜鸟们直观地学习。

Test()就是示例

  1. Sub Test2()
  2.     Dim arr As Variant, brr As Variant, strMsg As String
  3.    
  4.     ReDim arrResult(0) As String
  5.    
  6.     arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  7.    
  8.     If CheckValHasOK(arr, 11, brr) = True Then
  9.         arr = ""
  10.         'blGetAll 为false,只要有一组符合就退出
  11.         '输出结果为 1 组
  12.             '10+1=11
  13.         If MakeUpNumber(brr, 1, 0, 11, arr, False) = True Then
  14.             MsgBox "已完成,共有组合:" & UBound(arrResult) & "组"
  15.             strMsg = Join(arrResult, vbCrLf)
  16.             MsgBox strMsg
  17.         Else
  18.             MsgBox "没有合适的数字!"
  19.         End If
  20.         
  21.     Else
  22.         MsgBox "现有数字不满足凑数条件!"
  23.     End If
  24. End Sub

  25. Sub Test3()
  26.     Dim arr As Variant, brr As Variant, strMsg As String
  27.    
  28.     ReDim arrResult(0) As String
  29.    
  30.     arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  31.    
  32.     If CheckValHasOK(arr, 11, brr) = True Then
  33.         arr = ""
  34.         'blGetAll 为True,输出所有结果.blGetAll默认就是true
  35.         '输出结果为 11组
  36.             '10+1=11
  37.             '9+2=11
  38.             '8+3=11
  39.             '8+2+1=11
  40.             '7+4=11
  41.             '7+3+1=11
  42.             '6+5=11
  43.             '6+4+1=11
  44.             '6+3+2=11
  45.             '5+4+2=11
  46.             '5+3+2+1=11
  47.         If MakeUpNumber(brr, 1, 0, 11, arr, True) = True Then
  48.             MsgBox "已完成,共有组合:" & UBound(arrResult) & "组"
  49.             strMsg = Join(arrResult, vbCrLf)
  50.             MsgBox strMsg
  51.         Else
  52.             MsgBox "没有合适的数字!"
  53.         End If
  54.         
  55.     Else
  56.         MsgBox "现有数字不满足凑数条件!"
  57.     End If
  58. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-1-21 17:58 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2020-1-21 20:23 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-6-23 08:33 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-23 13:29 , Processed in 0.044563 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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