全ての組み合わせ
Posted feedbacks - VB.net
長い…が、 VBならこんなもんなのかな?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | Module Module1
Sub Main()
Dim li As Integer() = New Integer() {1, 2, 3, 4, 5}
Dim ls As Char() = New Char() {"a"c, "b"c, "c"c}
Dim cpg As New CrossProductGenerator(li, ls)
Dim e As IEnumerator(Of Object()) = cpg.GetEnumerator
While e.MoveNext
For i As Integer = 0 To e.Current.Length - 1
Console.Write(e.Current(i))
Next
Console.WriteLine()
End While
End Sub
End Module
Public Class CrossProductGenerator
Implements IEnumerable(Of Object())
Private _list As IEnumerable()
Public Sub New(ByVal ParamArray list() As IEnumerable)
_list = list
End Sub
Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of Object()) Implements IEnumerable(Of Object()).GetEnumerator
Return New Enumerator(_list)
End Function
Private Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
Return New Enumerator(_list)
End Function
Private Class Enumerator
Implements IEnumerator(Of Object())
Private _enumerators As IEnumerator()
Private _current As Object()
Private _state As Integer
Public Sub New(ByVal list As IEnumerable())
_enumerators = New IEnumerator(list.Length - 1) {}
For i As Integer = 0 To _enumerators.Length - 1
_enumerators(i) = list(i).GetEnumerator()
Next
_state = -1
_current = Nothing
End Sub
Public Sub Reset() Implements System.Collections.IEnumerator.Reset
For i As Integer = 0 To _enumerators.Length - 1
_enumerators(i).Reset()
Next
_state = -1
_current = Nothing
End Sub
Public ReadOnly Property Current() As Object() Implements System.Collections.Generic.IEnumerator(Of Object()).Current
Get
Return _current
End Get
End Property
Private ReadOnly Property Current1() As Object Implements System.Collections.IEnumerator.Current
Get
If _state <> 0 Then Throw New InvalidOperationException()
Return _current
End Get
End Property
Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
If _state > 0 Then Return False
If _state < 0 Then
For i As Integer = 0 To _enumerators.Length - 1
If Not _enumerators(i).MoveNext() Then
_state = 1
_current = Nothing
Return False
End If
Next
_state = 0
Else
Dim i As Integer = 0
While i < _enumerators.Length
If _enumerators(i).MoveNext Then Exit While
_enumerators(i).Reset()
_enumerators(i).MoveNext()
i += 1
End While
If i >= _enumerators.Length Then
_state = 1
_current = Nothing
Return False
End If
End If
_current = New Object(_enumerators.Length - 1) {}
For i As Integer = 0 To _enumerators.Length - 1
_current(i) = _enumerators(i).Current
Next
Return True
End Function
Public Sub Dispose() Implements IDisposable.Dispose
End Sub
End Class
End Class
|

zigorou #3400() Rating0/0=0.00
Pythonで表現すると下のようになります。
順番はこの通りでなくても構いません。返すものはリストと書きましたが、 なんらかの「一度に全部をメモリ上に作成しないリスト状のモノ」がある言語ではそちらを使う方がおすすめです。 数値や文字列を一つのリストに混在させるのがやっかいな言語では整数のリストに限定しても構いません。このお題はZIGOROuさんとのやりとりにヒントを得て作りました。 (しまった、先にブログで公開されてしまった→Yet Another Hackadelic - 直積の導出と考えうる全ての値を網羅したハッシュの生成)
追記:サンプル出力が間違っていたのでoceanさんの解答を使って出力し直しました。
[ reply ]