Excel·VBA数组排列函数
目录
- 1,排列代码思路
- 2,VBA数组排列函数
- 3,VBA数组重复排列函数
上一篇文章《Excel·VBA数组组合函数、组合求和》,实现了VBA组合功能,本文为VBA排列功能
《百度百科-排列》
排列:从n个不同元素中,取出m(m≤n)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列,一般称作选排列;当m=n时,这个排列被称作全排列
排列数:从n个不同元素中取出m个不同元素的所有不同排列的个数称为排列种数或称排列数
排列个数公式:P(n,m) = n!/(n-m)!,当n=m即全排列时为P(n) = n!
1,排列代码思路
从1-5共5个数字中选出4个数字,共120种排列,如图(部分截图)
按照上一篇文章“VBA组合函数”尾数循环的方式,观察每个排列的数字排列规律,可以发现每次尾数循环结束后,倒数第2列(即m-1)即进位+1(即2-3行);当进位列的数字达到最大值(即n)时,继续向前1列(即m-2)进位+1(即6-7行);当进位后的数字在之前出现过时,数字继续递增+1(即8-9行);进位结束后,排列在进位点之前的数字不变,之后的数字,按照1-5的顺序填入,且数字不重复;如此循环直至完成120种排列
VBA代码如下
2,VBA数组排列函数
选排列、全排列
Function permut_arr(arr, n&)'arr一维数组,内含m个元素,抽取n个进行排列,返回一维嵌套数组,每行为一个排列(数组从1开始计数)Dim i&, j&, k&, m&, kk&, result, x&, r&If LBound(arr) = 0 Then '转为从1开始计数arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))End Ifm = UBound(arr) - LBound(arr) + 1: ReDim brr&(1 To m): ReDim b&(1 To n)kk = Application.permut(m, n): ReDim result(1 To kk): ReDim res(1 To n)If n = 1 ThenFor i = 1 To mresult(i) = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Array(arr(i))))Nextpermut_arr = result: Exit FunctionEnd IfFor i = 1 To m 'arr初始位置brrbrr(i) = iNextDoFor i = 1 To n - 1 'b非尾数部分b(i) = brr(i)NextFor j = n To m '仅修改尾数b(n) = brr(j)For k = 1 To nres(k) = arr(b(k))Nextr = r + 1: result(r) = resNextx = n - 1: brr(x) = brr(x) + 1 '尾数循环结束后,n-1位进位y = Application.Match(brr(x), brr, 0)Do While (TypeName(y) <> "Error" And y < x) Or brr(x) > mIf y < x Then brr(x) = brr(x) + 1 '进位后,如之前位有重复值的继续+1'循环进位,直至完成所有进位If brr(x) > m Then If x > 1 Then x = x - 1: brr(x) = brr(x) + 1 Else Exit Doy = Application.Match(brr(x), brr, 0)LoopIf brr(1) > m Then Exit Do '所有排列完成For i = 1 To m '对brr数组x之后的按顺序赋值exist = False '初始为不存在For j = 1 To xIf brr(j) = i Then exist = True: Exit ForNextIf exist = False And x < m Then x = x + 1: brr(x) = iNextLoop Until r = kkpermut_arr = result
End Function
注意:代码中“排列个数”kk定义为Long类型,故最大值为2,147,483,647,如果实际应用中会超过该值的,需修改数据类型
Sub permut_arr测试()Dim arr, brrtm = Timerarr = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)brr = permut_arr(arr, 6)For Each b In brrr = r + 1: Cells(r, "a").Resize(1, UBound(b)) = bNextDebug.Print ("所有选排列写入完成,用时:" & Format(Timer - tm, "0.00"))
'--------------------转二维数组写入
' tm = Timer
' arr = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
' brr = TransposeArr(permut_arr(arr, 6), 2) '调用函数,将一维嵌套数组转为二维数组
' Cells(1, "a").Resize(UBound(brr), UBound(brr, 2)) = brr
' Debug.Print ("所有选排列写入完成,用时:" & Format(Timer - tm, "0.00")) '耗时
End Sub
注意:测试中调用了TransposeArr函数,将一维嵌套数组转为二维数组输出,代码详见《Excel·VBA数组组合函数、组合求和》
测试在excel表格中输出0-9共10个数字选6的排列形式,共151200种排列,输出结果与python的结果完全一致
python排列:《python排列组合函数》
3种输出排列方式耗时对比:151200种排列耗时秒数
python排列 | VBA排列一维嵌套数组 | VBA排列一维嵌套数组转二维数组 |
---|---|---|
15.5 | 5.16 | 1.46 |
可以看出,VBA排列输出一维嵌套数组2种写入方式都是非常快的
3,VBA数组重复排列函数
重复排列,相比上面的“选排列”和“全排列”是一种特殊的排列
重复排列:从n个不同元素中可重复地选取m个元素,按照一定的顺序排成一列,称作从n个元素中取m个元素的可重复排列
重复排列个数公式:n ^ m
代码思路:重复排列由于元素可重复使用,因而代码思路类似“选排列”,但仅考虑进位无需判断是否重复,仅原位置重置即可,故此代码较为简单(与10进制数字进位类似)
Function permut_repet(arr, n&)'arr一维数组,内含m个元素,重复抽取n个进行排列,返回一维嵌套数组,每行为一个排列(数组从1开始计数)Dim i&, m&, kk&, result, x&, r&If LBound(arr) = 0 Then '转为从1开始计数arr = WorksheetFunction.Transpose(WorksheetFunction.Transpose(arr))End Ifm = UBound(arr) - LBound(arr) + 1: ReDim b&(1 To n)kk = m ^ n: ReDim result(1 To kk): ReDim res(1 To n)For i = 1 To n '临时位置,index初始值b(i) = 1NextDoFor i = 1 To nres(i) = arr(b(i))Nextr = r + 1: result(r) = resx = n: b(x) = b(x) + 1 '修改尾数;当尾数循环结束后,进位Do While b(x) > m '进位,b中元素的最大值是m,从后向前判断b(x) = 1: x = x - 1 '尾数重置,进位If x = 0 Then Exit Do '完成所有排列b(x) = b(x) + 1LoopLoop Until r = kkpermut_repet = result
End Function
注意:代码中“排列个数”kk定义为Long类型,故最大值为2,147,483,647,如果实际应用中会超过该值的,需修改数据类型
Sub permut_repet测试()Dim arr, brrtm = Timerarr = Array(1, 2, 3, 4, 5)brr = permut_repet(arr, 3)For Each b In brrr = r + 1: Cells(r, "a").Resize(1, UBound(b)) = bNextDebug.Print ("所有重复排列写入完成,用时:" & Format(Timer - tm, "0.00"))
End Sub
从1-5共5个数字中重复选出3个数字,共125种排列,如图(部分截图)
Excel·VBA数组排列函数相关推荐
- Excel·VBA数组行列转换函数
目录 1,二维数组与一维嵌套数组互相转换函数 2,二维数组转换为指定行数/列数的函数 3,数组行列转置函数 1,二维数组与一维嵌套数组互相转换函数 <Excel·VBA数组组合函数.组合求和&g ...
- Excel VBA数组拓展列表(可以用作数据容器)
应用场景: 从数据库获取数据暂存,多表汇总,数据分析等,因为数组是存在于内存的,所以运行速度会非常快. 一.先总结数组的特性 数组转置必须在同过程或同函数内redim 否则报无效 redim: 起始 ...
- php的数组排列函数,常用PHP数组排序函数归纳
数组排序:数组中的元素能够以字母或数字顺序进行升序或降序排序. 常用的PHP数组排序函数 •sort() - 以升序对数组排序 •rsort() - 以降序对数组排序 •asort() - 根据值,以 ...
- php的数组排列函数,PHP实现的自定义数组排序函数与排序类示例
本文实例讲述了PHP实现的自定义数组排序函数与排序类.分享给大家供大家参考,具体如下: /* * 二维数组自定义排序函数 * uasort($arr,function_name) * **/ $arr ...
- Excel·VBA自定义正则表达式函数、使用
目录 正则表达式替换函数 应用1,提取1个字母+10个数字 应用2,中英文分割 应用3,提取11位手机号 应用4,指定文字替换 应用5,提取最后一个括号的内容 应用6,提取所有括号的内容 应用7,提取 ...
- php的数组排列函数,PHP下对数组进行排序的函数
经常,开发人员发现在PHP中使用这种数据结构对值或者数组元素进行排序非常有用.PHP提供了一些适合多种数组的排序函数,这些函数允许你在数组内部对元素进行排列,也允许用很多不同的方法对它们进行重新排序. ...
- EXCEL VBA数组使用的一些技巧和总结
数组声明 Dim myArray(1 to 50) as string 声明了一个下界为1,上界为50,类型为string的数组,当省略下界,如Dim myArray(50) as string时,其 ...
- Excel·VBA加权求和函数
Function WS(ByVal weight, ByVal data, Optional mode As Boolean = 1)'加权求和函数WS(权重数组, 数值数组, 模式),weight和 ...
- 【EXCEL VBA】字符函数
s = "ABCDEFG" 1.我想获取字符串s的左边三个字符 Left(s,3)则返回ABC 2.我想获取字符串s的右边三个字符 Right(s,3)则返回EFG ...
- Excel·VBA多条件筛选组合结果
Function strTOF(str$) As Boolean'用于计算字符串判断True/False,默认返回False'适用vba比较运算符:速度比较慢,但通用Dim i&, j& ...
最新文章
- 在 VS Code 里逛知乎、发文章?Zhihu on VSCode 来啦!重新定义内容创作!
- Csharp+Asp.net系列教程(四)
- html中dd dt的效果,html中dt dd
- ICDAR 2019论文:自然场景文字定位技术详解
- 服务器共享文件有访问台数限制,Win7/xp系统下共享文件夹最大连接数限制怎么解除...
- 同事1000行又臭又长 的类!被我用IDEA几分钟重构!真香!
- 第一次部署海康威视DEMO的一些坑,最终运行成功
- 深度可分离卷积(Depthwise seperable convolution)
- 电商公司ERP管理软件与旺店通、第三方仓库以及云仓的贯通解决方案
- ROMS海洋模式笔记
- B. 在哈尔滨的寒风中
- 仿滴滴首页车辆随机平滑移动,基于高德地图
- excel设定备选值
- 计算机通信过程详解 与 arp欺骗
- RK3288 EDP 调试
- java-php-net-python-社会公共常识科普网计算机毕业设计程序
- Dweb:使用WebRTC / WebTorrent构建弹性Web
- C语言制作个人通讯录管理系统—超详解(附源码)
- python基于django的商品比价平台
- Java jbcl.jar下载