VBAを用いた集合の理解 ③ 集合Aは集合Bの部分集合

先日から高校数学の学び直しとして、VBAを用いた集合の理解に挑戦している。
infoment.hatenablog.com
今日も、先日の続きから。
f:id:Infoment:20210516225711p:plain
先日までは、要素aが集合Aに含まれるか否かの判定を、そして更に集合Aを
一次元配列として、要素aの追加と削除を行ってみた。

今回は、集合Aが集合Bに含まれるか?の判定を行ってみる。

  • A=B:集合Aと集合Bは等しい ⇒ 配列Aと配列Bは等しい
  • A⊂B:集合Aは集合Bの部分集合 ⇒ 配列Aは配列Bに含まれる
  • A⊆B:A=BまたはA⊂B

manabitimes.jp

クラスモジュール(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

結果がこちら。
f:id:Infoment:20210517192907p:plain

段々と充実してきた。
次回は、和集合と積集合に挑戦です。

参考まで。