ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 【通用数组算法】生成序列、组合、排列 结果

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-3-29 17:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:循环和遍历
Function Arr_SerialCombinPermut(m&, n&, Optional z& = 0, Optional l& = 0)
    Dim i&, j&, k&, t&
    If z = 0 Then k = (m - l + 1) ^ n
    If z = 1 Then k = WorksheetFunction.Combin(m, n): l = 1
    If z = 2 Then k = WorksheetFunction.Permut(m, n): ReDim c&(1 To m)
   
    ReDim a&(1 To n), b&(k - 1, 1 To n)      '创建两个数组,分别用于存放3个“数种”各数位的数码和3个“数种”的序列。
    For j = 1 To n                           '给序列第一个位置赋值
        If z = 0 Then a(j) = l                '自然数序列第一个,3位分别为0 0 0
        If z = 1 Then a(j) = j                '组合数序列第一个,3位分别为1 2 3,
        If z = 2 Then a(j) = j: c(j) = 1       '排列数序列第一个,3为分别为1 2 3,同时创建状态监测数组,用于监视数码是否被使用,如已使用则状态为1,否则为0。
        b(0, j) = a(j) 'ar(a(j))
    Next
   
    For i = 1 To k - 1                ' 序列循环头
        For j = n To 1 Step -1                           '从低位到高位遍历每一个数的数位。
            If z = 0 Then
                If a(j) < m Then a(j) = a(j) + 1: Exit For                '对自然数序列,该数位中要装填的数码是前一个自然数的对应数位中的数码+1。否则将“进位”到高一位,并对高一位进行相似的处理。
            ElseIf z = 1 Then
                If a(j) < m - n + j Then a(j) = a(j) + 1: Exit For        '对组合数序列,该数位的数码也+1,但最大不得超过该数位(该次选择)能选取的最大数码(最多种数)。否则将“进位”到高一位
            Else 'If z = 2 Then
                c(a(j)) = 0                                               '对排列数序列,将每一位使用的数码恢复为未使用。
                For t = a(j) + 1 To m                                     '搜寻尚未使用的数码,
                    If c(t) = 0 Then Exit For
                Next
                If t <= m Then c(t) = 1: a(j) = t: Exit For               '然后装填在该数位,并标记该数码已使用。
            End If
        Next
        For j = j + 1 To n
            If z = 0 Then                   '对自然数序列,因为产生了“进位”,需要将低一位的数位中装填数码恢复为“l”(数码列表中的最小的那个)。
                a(j) = l
            ElseIf z = 1 Then               '对组合数序列,因为也产生了“进位”,低一位的要装填的数码个数要多一个。
                a(j) = a(j - 1) + 1
            Else 'If z = 2 Then                   '对排列数序列,
                For t = 1 To m                    '低一位的要装填的应该是尚未使用的数码中的第一个。
                    If c(t) = 0 Then Exit For
                Next
                c(t) = 1: a(j) = t                '通过紧前循环步骤,找出了尚未使用的数码中的第一个,并将其装填在该数位。
            End If
        Next
        For j = 1 To n
            b(i, j) = a(j) 'ar(a(j))
        Next
    Next
    Arr_SerialCombinPermut = b
End Function

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-4-4 00:54 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2015-3-27 17:12
其它两个算法很简单,就是从m个元素中提取n个元素进行不重复组合,或进行排列组合。

高手!信手拈来都精品

TA的精华主题

TA的得分主题

发表于 2015-4-4 12:51 | 显示全部楼层
大力火手 发表于 2015-4-4 00:54
高手!信手拈来都精品

老师,这个怎样做啊,求高手,求大神,关于排列组合
http://club.excelhome.net/thread-1196028-1-1.html

TA的精华主题

TA的得分主题

发表于 2015-7-6 21:51 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
学习中,谢谢!!

TA的精华主题

TA的得分主题

发表于 2015-8-14 22:34 | 显示全部楼层
拜读群主的大贴【通用数组算法】生成序列、组合、排列 结果
http://club.excelhome.net/thread-1194281-1-1.html,真是踏破铁鞋才找到,多谢了!本人常用排列方法演算彩票,群主的程序正好适用。我已将n改成7,以适用7位数,但还有一点,彩票1-5位是递增,6-7位是递增,如果每一位置的数字存在多选,群主的程序可能会出现高位的数字小于低位数字的现象,麻烦群主修改一下,谢谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-8-15 18:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
aaa0548 发表于 2015-8-14 22:34
拜读群主的大贴【通用数组算法】生成序列、组合、排列 结果
http://club.excelhome.net/thread-1194281-1- ...

你的要求完全没有说清楚。

TA的精华主题

TA的得分主题

发表于 2015-8-15 20:44 | 显示全部楼层
香川群子 发表于 2015-8-15 18:50
你的要求完全没有说清楚。

彩票的排列:1, 5, 10,20, 33, 2,10,即1-5位的数值是递增的,后两位在1-12之间选两个数,第6位的数值需小于第7位。假设第1位待选数值有1,5,7,9四个,第2位有5,8,10三个,那前两位的排列组合在彩票中只会出现1  5  ,1  8 ,  1  10,  5  8,  5  10, 7  8,  7  10,  9  10; 而你的程序会出现5  5,  9  5,  9  8组合。我的要求是排列后的组合应剔除这些,保留下来的组合的前5位数应是递增的数字,不能出现有相等或小于前一位数字的情况。后两位数字不与前5位相比较,第6位小于第7位。不知我说明白了没有?

TA的精华主题

TA的得分主题

发表于 2017-7-12 17:01 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
收藏学习中....

TA的精华主题

TA的得分主题

发表于 2021-9-7 18:06 | 显示全部楼层
香川群子 发表于 2015-3-27 17:11
我知道你最喜欢能自动忽略空白单元格的组合算法了……

本帖代码中第一个序列算法,稍加修改即可做到。 ...

老师 像这种组合超多的情况已经超过表格限制的情况。 怎么做一个 随机的组合 比方说 随机组合出50万组数据~每列随机 不重复的 达到数量就停止 用字典不现实!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-28 23:28 , Processed in 0.039103 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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