ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E问E答 > Excel VBA > 如何列出从1-N的数中取M个数做加法的组合?

如何列出从1-N的数中取M个数做加法的组合?

作者:绿色风 分类: 时间:2022-08-17 浏览:177
楼主
amulee
Q:如何列出从1-N的数中取M个数做加法的组合?
A:参考以下代码。
  1. Sub 加法算法()
  2.     Dim arrYS, arrJG, arrTemp
  3.     Dim MyM&, MyN&, i, j, K, iTemp, PoseTemp
  4.     '初始化原始数组
  5.     MyM = [d1]
  6.     ReDim arrYS(1 To MyM)
  7.     For i = 1 To UBound(arrYS)
  8.         arrYS(i) = i
  9.     Next i
  10.     '取出多少个数
  11.     MyN = [d2]
  12.     '初始化临时数组
  13.     ReDim arrTemp(1 To MyM) As Integer
  14.     For i = 1 To MyN
  15.         arrTemp(i) = 1
  16.     Next i
  17.     K = 1
  18.     ReDim arrJG(1 To nx(MyM) / nx(MyN) / nx(MyM - MyN))    '定义结果数组
  19.     arrJG(K) = OutputArrJG(arrYS, arrTemp)                 '输出第一个结果
  20.     '开始循环
  21.     Do
  22.         '查找10组合,找到就交换
  23.         For i = 1 To MyM - 1
  24.             If arrTemp(i) = 1 And arrTemp(i + 1) = 0 Then
  25.                 arrTemp(i) = 0
  26.                 arrTemp(i + 1) = 1
  27.                 PoseTemp = i
  28.                 Exit For
  29.             End If
  30.         Next
  31.         '交换之前的1到最前面
  32.         iTemp = 0
  33.         For i = PoseTemp To 1 Step -1
  34.             If arrTemp(i) = 1 Then
  35.                 For j = 1 To PoseTemp
  36.                     If arrTemp(j) = 0 Then
  37.                         iTemp = j
  38.                         Exit For
  39.                     End If
  40.                 Next j
  41.                 If iTemp > i Then Exit For
  42.                 arrTemp(iTemp) = 1
  43.                 arrTemp(i) = 0
  44.             End If
  45.         Next i
  46.         '输出数组
  47.         K = K + 1
  48.         arrJG(K) = OutputArrJG(arrYS, arrTemp)
  49.         '判断是否结束
  50.         For i = 1 To MyM
  51.             If arrTemp(i) = 1 Then
  52.                 iTemp = i
  53.                 Exit For
  54.             End If
  55.         Next i
  56.         '判断1是否已经全到右边
  57.         If iTemp > (MyM - MyN) Then Exit Do
  58.     Loop
  59.     '结果输出
  60.     [a2:a65536].ClearContents
  61.     [a2].Resize(UBound(arrJG), 1) = Application.Transpose(arrJG)
  62. End Sub
  63. '数组结果输出函数
  64. Function OutputArrJG(ByVal MyArr, ByVal MyArrTemp)
  65.     Dim strAA As String
  66.     Dim i&
  67.     For i = 1 To UBound(MyArrTemp)
  68.         If MyArrTemp(i) = 1 Then strAA = strAA & MyArr(i) & "+"
  69.     Next i
  70.     strAA = Left(strAA, Len(strAA) - 1)
  71.     OutputArrJG = strAA & "=" & Evaluate(strAA)
  72. End Function
  73. Function nx(n)
  74.   Dim i%
  75.   nx = 1
  76.   For i = 2 To n
  77.     nx = nx * i
  78.   Next i
  79. End Function



VBA-加法组合.rar
2楼
donghan
哈,楼主好快呀,收藏学习了
3楼
donghan
楼主能不能解释一下啊,我复制完代码还是不懂怎么用
4楼
amulee
工作表内其实有说明,关键是组合的算法

在D1内输入数字总数,在D2内输入取多少个数

组合算法
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标
代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
到了最后一个组合。
例如求5中选3的组合:
1 1 1 0 0 //1,2,3
1 1 0 1 0 //1,2,4
1 0 1 1 0 //1,3,4
0 1 1 1 0 //2,3,4
1 1 0 0 1 //1,2,5
1 0 1 0 1 //1,3,5
0 1 1 0 1 //2,3,5
1 0 0 1 1 //1,4,5
0 1 0 1 1 //2,4,5
0 0 1 1 1 //3,4,5
5楼
liuguansky
不错,学习了。
6楼
赵文竹
不错,学习了!但运行时提示有错误“子过程或函数未定义”,请楼主检查一下。谢谢了
7楼
donghan
我也是显示这个提示
8楼
donghan
如果题目改成A1:A10中的10个任意数字该过程可以算么?
9楼
amulee
附件和代码以更新,少了一个计算个数的自定义函数。

如果是A1:A10的数字,也可以通过这个来运算。在那个自定义输出函数里面稍作修改,将其改为A1:A10单元格引用即可。
10楼
donghan
楼主你好,VBA对我来说有点难,想修改你的代码不知道从哪儿修改,再问一下如果取数时数字可以重复,你的代码应该怎样修改呢?
11楼
amulee
两段代码的思路是完全不同的。数字别数太大,不然计算慢。
  1. Sub 加法算法()  '数字可重复
  2.     Dim Nt%, Nm%, i&, j%
  3.     Dim ArrTemp, ArrJG, Temp
  4.     Nt = [D1]
  5.     Nm = [D2]
  6.     ReDim ArrJG(1 To Nt ^ Nm, 0 To 0)
  7.     ReDim ArrTemp(1 To Nm)
  8.     For i = 1 To Nm - 1
  9.         ArrTemp(i) = 1
  10.     Next i
  11.     ArrTemp(Nm) = 0
  12.     For i = 1 To UBound(ArrJG)
  13.         ArrTemp(Nm) = ArrTemp(Nm) + 1
  14.         For j = Nm To 2 Step -1
  15.             If ArrTemp(j) > Nt Then
  16.                 ArrTemp(j - 1) = ArrTemp(j - 1) + 1
  17.                 ArrTemp(j) = ArrTemp(j) - Nt
  18.             Else
  19.                 Exit For
  20.             End If
  21.         Next j
  22.         Temp = Join(ArrTemp, "+")
  23.         ArrJG(i, 0) = Temp & "=" & Evaluate(Temp)
  24.     Next i
  25.     Range("A1:A1048576").Clear
  26.     Range("A1").Resize(UBound(ArrJG), 1) = ArrJG
  27. End Sub



VBA-加法组合-2.rar
12楼
donghan
下载学习了

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap