VBAを用いた集合の理解 ③ 集合Aは集合Bの部分集合
先日から高校数学の学び直しとして、VBAを用いた集合の理解に挑戦している。
infoment.hatenablog.com
今日も、先日の続きから。
先日までは、要素aが集合Aに含まれるか否かの判定を、そして更に集合Aを
一次元配列として、要素aの追加と削除を行ってみた。
今回は、集合Aが集合Bに含まれるか?の判定を行ってみる。
- A=B:集合Aと集合Bは等しい ⇒ 配列Aと配列Bは等しい
- A⊂B:集合Aは集合Bの部分集合 ⇒ 配列Aは配列Bに含まれる
- A⊆B:A=BまたはA⊂B
クラスモジュール(MathSet)
まず、A⊂Bを作成する。配列Aの要素が全て配列Bに含まれていて、且つ、
配列Bの要素が一つでもAに含まれなければ、Bの一部がAということになる。
前々回作成した ↓ こちらは、今回も使用するので再掲。
' 指定文字列が、ある集合の要素であるか否かを返す。 ' a ∈ A:aは集合Aの要素である。 Public Function IsElement(ByVal element As Variant, _ ByVal target_set As Variant, _ Optional LookAt As XlLookAt = xlWhole) As Boolean ' 集合ではないものが指定された場合、Falseを返す。 If Not IsArray(target_set) Then Exit Function ' 配列内の値と順にelementを照合し、同じものがある時点でTrueを返す。 ' 従って、この関数はtarget_set内で複数の同じ値が含まれる場合を除外しない。 Dim a As Variant If LookAt = xlPart Then element = "*" & element & "*" For Each a In target_set If a Like element Then IsElement = True Exit Function End If Next End Function
' 集合Aが、集合Bに含まれるか否かを確認する(真部分集合)。 ' A ⊂ B ' ※配列Aと配列Bの次元数が一致していなくとも、配列Aの ' 全ての要素が配列Bに包含されているならば、Trueを返す。 Public Function IsProperSubset(ByVal set_A As Variant, _ ByVal set_B As Variant) As Boolean If Not IsArray(set_A) Or Not IsArray(set_B) Then Exit Function Dim a As Variant ' BにないものがAにあれば、その時点で部分集合ではない。 For Each a In set_A If Not IsElement(a, set_B) Then Exit Function End If Next ' 上述の処理を経たうえで、Bにあるものが全てAにあれば、 ' AとBは等しいといえる(真部分集合とは言えない)。 ' 従って、BにあってAにないものが一つでも存在する時点で、 ' AはBの真部分集合(A⊂B)と言える。 For Each a In set_B If Not IsElement(a, set_A) Then IsProperSubset = True End If Next End Function
次いで各要素の総当たりにより、A=Bを判定する。
' 集合Aが、集合Bと等しいか否かを確認する。 ' A=B ' ※配列Aと配列Bの次元数が一致していなくとも、配列Aと ' 配列Bの要素が互いにすべて含まれるならば、Trueを返す。 Public Function IsEqual(ByVal set_A As Variant, _ ByVal set_B As Variant) As Boolean If Not IsArray(set_A) Or Not IsArray(set_B) Then Exit Function End If Dim a As Variant For Each a In set_A If Not IsElement(a, set_B) Then Exit Function End If Next For Each a In set_B If Not IsElement(a, set_A) Then Exit Function End If Next IsEqual = True End Function
最後に、こちらを作成。
' 集合Aが、集合Bに含まれるか否かを確認する(部分集合)。 ' A ⊆ B ' ※配列Aと配列Bの次元数が一致していなくとも、配列Aの ' 全ての要素が配列Bに包含されているかまたは等しいなら ' Trueを返す。 Public Function IsSubset(ByVal set_A As Variant, _ ByVal set_B As Variant) As Boolean If Not IsArray(set_A) Or Not IsArray(set_B) Then ElseIf IsProperSubset(set_A, set_B) Or IsEqual(set_A, set_B) Then IsSubset = True End If End Function
標準モジュール
それでは、簡単なテストを一つ。
Sub test() Dim MS As VBAProject.MathSet Set MS = New VBAProject.MathSet Dim 果物1 As Variant 果物1 = Array("りんご", "みかん", "ばなな") Dim 果物2 As Variant 果物2 = Array("りんご", "みかん", "ばなな") Debug.Print "果物2⊂果物1:" & MS.IsProperSubset(果物2, 果物1) Debug.Print "果物2=果物1:" & MS.IsEqual(果物2, 果物1) Debug.Print "果物2⊆果物1:" & MS.IsSubset(果物2, 果物1) Dim 果物3 As Variant 果物3 = Array("ぶどう", "れもん") Debug.Print "果物3⊂果物1:" & MS.IsProperSubset(果物3, 果物1) Debug.Print "果物3=果物1:" & MS.IsEqual(果物3, 果物1) Debug.Print "果物3⊆果物1:" & MS.IsSubset(果物3, 果物1) Dim 果物4 As Variant 果物4 = Array("りんご", "ばなな") Debug.Print "果物4⊂果物1:" & MS.IsProperSubset(果物4, 果物1) Debug.Print "果物4=果物1:" & MS.IsEqual(果物4, 果物1) Debug.Print "果物4⊆果物1:" & MS.IsSubset(果物4, 果物1) End Sub
結果がこちら。
段々と充実してきた。
次回は、和集合と積集合に挑戦です。
参考まで。