为了避免术语的问题:我写了一个小程序:
Dim aaItems : aaItems = Array(_
Array("small", "med", "lg", "xl") _
, Array("red", "blue", "green", "white") _
, Array("pocket", "no-pocket") _
)
Dim oOdoDemo : Set oOdoDemo = New cOdoDemo.init(aaItems)
oOdoDemo.run 33
,这就是它的输出:
0: small red pocket
1: small red no-pocket
2: small blue pocket
3: small blue no-pocket
4: small green pocket
5: small green no-pocket
6: small white pocket
7: small white no-pocket
8: med red pocket
9: med red no-pocket
10: med blue pocket
11: med blue no-pocket
12: med green pocket
13: med green no-pocket
14: med white pocket
15: med white no-pocket
16: lg red pocket
17: lg red no-pocket
18: lg blue pocket
19: lg blue no-pocket
20: lg green pocket
21: lg green no-pocket
22: lg white pocket
23: lg white no-pocket
24: xl red pocket
25: xl red no-pocket
26: xl blue pocket
27: xl blue no-pocket
28: xl green pocket
29: xl green no-pocket
30: xl white pocket
31: xl white no-pocket
32: small red pocket
如果看起来就像一颗种子到你的问题的解决方案,只要这么说,我就会发布cOdoDemo类的代码。
代码cOdoDemo:
'' cOdoDemo - Q&D combinations generator (odometer approach)
'
' based on ideas from:
' !! http://www.quickperm.org/index.php
' !! http://www.ghettocode.net/perl/Buzzword_Generator
' !! http://www.dreamincode.net/forums/topic/107837-vb6-combinatorics-lottery-problem/
' !! http://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n
Class cOdoDemo
Private m_nPlaces ' # of places/slots/digits/indices
Private m_nPlacesUB ' UBound (for VBScript only)
Private m_aLasts ' last index for each place => carry on
Private m_aDigits ' the digits/indices to spin around
Private m_aaItems ' init: AoA containing the elements to spin
Private m_aWords ' one result: array of combined
Private m_nPos ' current increment position
'' init(aaItems) - use AoA of 'words' in positions to init the
'' odometer
Public Function init(aaItems)
Set init = Me
m_aaItems = aaItems
m_nPlacesUB = UBound(m_aaItems)
m_nPlaces = m_nPlacesUB + 1
ReDim m_aLasts( m_nPlacesUB)
ReDim m_aDigits(m_nPlacesUB)
ReDim m_aWords( m_nPlacesUB)
Dim nRow
For nRow = 0 To m_nPlacesUB
Dim nCol
For nCol = 0 To UBound(m_aaItems(nRow))
m_aaItems(nRow)(nCol) = m_aaItems(nRow)(nCol)
Next
m_aLasts(nRow) = nCol - 1
Next
reset
End Function ' init
'' reset() - start afresh: all indices/digit set to 0 (=> first word), next
'' increment at utmost right
Public Sub reset()
For m_nPos = 0 To m_nPlacesUB
m_aDigits(m_nPos) = 0
Next
m_nPos = m_nPlacesUB
End Sub ' reset
'' tick() - increment the current position and deal with carry
Public Sub tick()
m_aDigits(m_nPos) = m_aDigits(m_nPos) + 1
If m_aDigits(m_nPos) > m_aLasts(m_nPos) Then ' carry to left
For m_nPos = m_nPos - 1 To 0 Step -1
m_aDigits(m_nPos) = m_aDigits(m_nPos) + 1
If m_aDigits(m_nPos) <= m_aLasts(m_nPos) Then ' carry done
Exit For
End If
Next
For m_nPos = m_nPos + 1 To m_nPlacesUB ' zero to right
m_aDigits(m_nPos) = 0
Next
m_nPos = m_nPlacesUB ' next increment at utmost right
End If
End Sub ' tick
'' map() - build result array by getting the 'words' for the
'' indices in the current 'digits'
Private Sub map()
Dim nIdx
For nIdx = 0 To m_nPlacesUB
m_aWords(nIdx) = m_aaItems(nIdx)(m_aDigits(nIdx))
Next
End Sub ' map
'' run(nMax) - reset the odometer, tick/increment it nMax times and
'' display the mapped/translated result
Public Sub run(nMax)
reset
Dim oPad : Set oPad = New cPad.initWW(Len(CStr(nMax)) + 1, "L")
Dim nCnt
For nCnt = 0 To nMax - 1
map
WScript.Echo oPad.pad(nCnt) & ":", Join(m_aWords)
tick
Next
End Sub ' run
End Class ' cOdoDemo
一些提示/备注:想那genererates所有组合6里程表的数字顺序地/位(7?)。现在设想一个里程表,可以让你为每个地点/插槽指定一个序列/有序的“数字”/字/项目集。该规范由aaItems完成。
这是CPAD()中的代码,在使用.RUN:
''= cPad - Q&D padding
Class cPad
Private m_nW
Private m_sW
Private m_sS
Private m_nW1
Public Function initWW(nW, sW)
m_nW = nW
m_nW1 = m_nW + 1
m_sW = UCase(sW)
m_sS = Space(nW)
Set initWW = Me
End Function
Public Function initWWC(nW, sW, sC)
Set initWWC = initWW(nW, sW)
m_sS = String(nW, sC)
End Function
Public Function pad(vX)
Dim sX : sX = CStr(vX)
Dim nL : nL = Len(sX)
If nL > m_nW Then
Err.Raise 4711, "cPad::pad()", "too long: " & nL & " > " & m_nW
End If
Select Case m_sW
Case "L"
pad = Right(m_sS & sX, m_nW)
Case "R"
pad = Left(sX & m_sS, m_nW)
Case "C"
pad = Mid(m_sS & sX & m_sS, m_nW1 - ((m_nW1 - nL) \ 2), m_nW)
Case Else
Err.Raise 4711, "cPad::pad() Unknown m_sW: '" & m_sW & "'"
End Select
End Function
End Class ' cPad
对不起失踪文档。我会尽力回答你所有的问题。
就是这样!唯一的小问题是#32和#0是相同的,但我可以很容易地忽略重复。 –
我不得不做一些小修改,但这正是我所需要的。再次感谢! –