我正在寻找一种适用于下表的简单算法:
在第一列中,您可以看到约束。算法应该使用第二列来输出迭代,这应该像这样完成:
0 0 0
0 0 1
........
0 0 29
0 1 0
........
0 1 29
0 2 0
0 2 1
........
........
27 9 29
28 0 0
........
........
28 9 29
目前我有以下代码:
Dim wksSourceSheet As Worksheet
Set wksSourceSheet = Worksheets("Solver")
Dim lngLastRow As Long
Dim lngLastColumn As Long
With wksSourceSheet
lngLastRow = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count)
lngLastColumn = IIf(IsEmpty(.Cells(1, .Columns.Count)), _
.Cells(1, .Columns.Count).End(xlToLeft).Column, .Columns.Count)
Dim intRowOuter As Integer
Dim intRowInner As Integer
For intRowOuter = 2 To lngLastRow
.Cells(intRowOuter, lngLastColumn).Value = 0
Next intRowOuter
For intRowOuter = lngLastRow To 2 Step -1
For intRowInner = lngLastRow To intRowOuter Step -1
Dim constraint As Integer
Dim intConstraintCounter As Integer
intConstraint = .Cells(intRowInner, 1)
For intConstraintCounter = 1 To intConstraint
.Cells(intRowInner, lngLastColumn).Value = intConstraintCounter
Next intStampCounter
Next intRowInner
Next intRowOuter
End With
这可能是一种正确的方法,但有些不正确。我不幸被困住了,所以我会很感激帮助解决这个问题。
答案 0 :(得分:1)
我建议使用一个数组来存储约束,使用一个来表示计数器。
Dim MaxNum() As Long
Dim myCounter() As Long
ReDim MaxNum(1 To NumDigits)
ReDim myCounter(1 To NumDigits)
接下来,您需要初始化MaxNum
。这可能涉及循环包含约束的单元格。类似的东西:
Dim constraintRange As Range
Dim i As integer
Set constraintRange = wksSourceSheet.Range("A2:A4")
For i = 1 to numDigits
MaxNum(i) = constraintRange.Cells(i,1).Value
Next i
现在我们只需编写增量计数器功能!这个想法非常简单,我们只是从最不重要的数字到最重要的数字。我们递增LSD,如果有溢出,我们将其设置为0,然后将1加到下一个数字。它看起来像这样:
Sub IncrNum(ByRef myNum() As Long, ByRef MaxNum() As Long)
Dim i As Integer
For i = LBound(myNum) To UBound(myNum)
myNum(i) = myNum(i) + 1
If myNum(i) > MaxNum(i) Then 'Overflow!
myNum(i) = 0 'Reset digit to 0 and continue
Else
Exit For 'No overflow so we can just exit
End If
Next i
End Sub
这只是一个for-loop!我认为这将是最干净的解决方案:)
注意:要使用此功能,您只需执行IncrNum(myCounter, MaxNum)
即可。这会将myCounter
的值更改为序列中的下一个值。从这里开始,您可以通过dstRange = myCounter
粘贴到范围。
在我自己的测试中,我使用while循环打印出所有值。它看起来像这样:
Do While Not areEqual(MaxNum, myCounter)
Call IncrNum(myCounter,MaxNum)
outRange = myCounter
Set outRange = outRange.Offset(1, 0)
Loop
areEqual
只是一个函数,如果参数包含相同的值,则返回true。如果你愿意,我可以提供我的代码,否则我会把它留在外面,以保持我的答案尽可能正常。
答案 1 :(得分:1)
也许可以修改这样的东西以满足您的需求。它使用carry模拟加法:
Sub Clicker(MaxNums As Variant)
Dim A As Variant
Dim i As Long, j As Long, m As Long, n As Long
Dim sum As Long, carry As Long
Dim product As Long
m = LBound(MaxNums)
n = UBound(MaxNums)
product = 1
For i = m To n
product = product * (1 + MaxNums(i))
Next i
ReDim A(1 To product, m To n)
For j = m To n
A(1, j) = 0
Next j
For i = 2 To product
carry = 1
For j = n To m Step -1
sum = A(i - 1, j) + carry
If sum > MaxNums(j) Then
A(i, j) = 0
carry = 1
Else
A(i, j) = sum
carry = 0
End If
Next j
Next i
Range(Cells(1, 1), Cells(product, n - m + 1)).Value = A
End Sub
用过:
Sub test()
Clicker Array(3, 2, 2)
End Sub
产生:
答案 2 :(得分:0)
x%10
或x Mod 10
给出余数,这样你就得到x的最后一位数。
由于您的问题是专门要求每个数字不超过463857.您可以让计数器从000000递增到463857并且只输出/使用满足以下条件的数字:
IF(x%10 <= 7 AND x%100 <=57 AND x%1000 <= 857 AND x%10000 <=3857 AND x%100000 <= 63857 AND x <= 463857)
THEN //perform task.