|
本帖最后由 香川群子 于 2014-8-22 13:49 编辑
比如,生成十进制(最大元数n=9)的4位数 0000 - 9999
或 五进制 (最大元数n=4)的4位数 0000 - 4444 (0005、2345等超过最大元素4的数不合法,要排除)
或 二进制 (最大元数n=1)的8位数 0000 0000 - 1111 1111
代码如下:
- Sub GetSeqTest()
- tms = Timer
- ar1 = GetSeqArr(8, 1) '生成 8位 二进制(区间0-1、最大n=1)的数的集合
- ar2 = GetSeqArr(4, 4) '生成 4位 五进制(区间0-4、最大n=4)的数的集合
- ar3 = GetSeqArr(4, 9) '生成 4位 十进制(区间0-9、最大n=9)的数的集合
- ar4 = GetSeqArr(4, 2, 1) '生成 4位 准二进制(区间1-2、最大n=2、最小 l =1 )的数的集合
- ar5 = GetSeqArr(4, 6, 2) '生成 4位 准五进制(区间2-6、最大n=6、最小 l =2 )的数的集合
- '如果实际是要在VBA代码过程中使用,则无需输出结果。
- '下面是输出例子-1 如实际是在VBA中代码过程中使用,则无需输出
- arr = GetSeqArr(3, 9) '生成 3位 十进制(区间0-9、最大n=9)的数的集合、并输出结果到工作表
- [a1].CurrentRegion = "": [a1].Resize(UBound(arr), UBound(arr, 2)) = arr '输出000 - 999 共1000个数
- MsgBox Format(Timer - tms, "0.000s ") & UBound(arr)
- arr = GetSeqArr(4, 2, 1) '生成 4位 准二进制(区间1-2、最大n=2、最小 l =1)的数的集合、并输出结果到工作表
- [a1].CurrentRegion = "": [a1].Resize(UBound(arr), UBound(arr, 2)) = arr '输出1111 - 2222 共16个数
- MsgBox Format(Timer - tms, "0.000s ") & UBound(arr)
- End Sub
- Function GetSeqArr(m&, n&, Optional l& = 0) '自定义函数
- Dim i&, j&, k&
- k = (n - l + 1) ^ m '计算结果总数=区间个数的m次幂
- ReDim a&(k, 1 To m) '定义存放结果的数组a
- For j = 1 To m
- a(0, j) = l: a(k, j) = l '进行初始化赋值 = l (默认=0)
- Next
- For i = 1 To k '遍历产生结果
- For j = m To 1 Step -1 '倒序(实质上是从个位开始升序检查)检查是否需要按n+1进制进位
- If a(k, j) = n Then a(k, j) = l Else a(k, j) = a(k, j) + 1: Exit For
- '如当前位置=进位最大值n 则进位(本位归零 = l 、递归检查上一位) 否则本位+1后结束本次计算赋值
- Next
- '请注意上述处理是在数组最后一行第 k 行进行。 所以最后输出时第k行不要输出的。
-
- '以下把赋值结束后的结果写入结果数组第 i 行
- For j = 1 To m
- a(i, j) = a(k, j)
- Next
- Next
- GetSeqArr = a
- End Function
复制代码 我的这个算法,尤其是在数组中的计算过程是超快的。
比String方式合成要快很多倍。
如果只需在VBA代码过程中遍历计算使用,而不需要逐个写入数组,效率会更高。
此时,定义数组a为单行一维数组即可: ReDim a&(1 To m)
补充:
2014年8月22日更新、增加了起始初值 l 的设置(默认 l =0)
这样适用范围更广…………如可以要求从 1111 循环到 4444、或者要求从 2222 循环到 8888
|
评分
-
2
查看全部评分
-
|