C#

【C#】HashSetクラスとSortedSetクラス ~C#で集合を扱う~

この記事では、C#で集合を扱う方法であるHashSet<T>クラスとSortedSet<T>クラスについて簡単なコードで解説します。集合のことをセットといいます。以降、HashSet<T>クラスのことをHashSet、SortedSet<T>クラスのことをSortedSetと略します。

HashSet<T>クラスとSortedSet<T>クラス

HashSetクラスとSortedSetクラスはいずれもジェネリックコレクションの一種で、セットを扱います。セットとは要素に重複がないコレクションで、数学の集合のように扱うことができます。また、両方とも配列やListのように要素番号で要素の値にアクセスすることはできません。

ジェネリックコレクションを使うために、下記のusingディレクティブが必要です。

using System.Collection.Generic;

HashSetとSortedSetの違いは、HashSetは要素に順番がないのに対してSortedSetの要素はソートされた順になっている点です。

HashSetとSortedSetのコレクションとしての操作をするプロパティとメソッド

HashSetとSortedSetではプロパティやメソッドの多くが共通しています。ここでは、コレクションとしての操作をするプロパティやメソッドを解説します。

宣言と初期化

HashSetとSortedSetの宣言と初期化は他のジェネリックコレクションと同じです。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>();
        Console.WriteLine("hst1:[{0}]", string.Join(" ", hst1));

        var hst2 = new HashSet<int>() { 3, 5, 1, 2, 4, 1, 2 };
        Console.WriteLine("hst2:[{0}]", string.Join(" ", hst2));


        //SortedSet
        var sst1 = new SortedSet<int>();
        Console.WriteLine("sst1:[{0}]", string.Join(" ", sst1));

        var sst2 = new SortedSet<int>() { 3, 5, 1, 2, 4, 1, 2 };
        Console.WriteLine("sst2:[{0}]", string.Join(" ", sst2));
    }
}

出力結果

hst1:[]
hst2:[3 5 1 2 4]
sst1:[]
sst2:[1 2 3 4 5]

9行目と12行目でHashSetの宣言と初期化を行っています。9行目は空のHaseSetオブジェクトを宣言しています。12行目は初期化子を使って要素を追加しています。

17行目と20行目でSortedSetの宣言と初期化を行っています。17行目は空のSortedSetオブジェクトを20行目は初期化子を使って要素を追加しています。

両者とも12行目と20行目で重複のある値を入力していますが、次の行(13行目と21行目)で表示されているデータは重複がありません。このようにHashSetとSortedSetでは重複のあるデータは無視されます。また、13行目のHaseSetの表示は要素の追加された順になっていますが、21行目のSortedSetの表示は要素の値の昇順になっています。

Countプロパティで要素数を取得する

HashSetやSortedSetオブジェクトの要素数を取得するにはCountプロパティを使用します。

下記コードでは10行目と16行目でHashSetとSortedSetオブジェクトの要素数を取得しています。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst = new HashSet<int>() { 3, 5, 1, 2, 4, 1, 2 };
        Console.WriteLine("hstの要素数は{0}です",hst.Count);
        Console.WriteLine("hst:[{0}]", string.Join(" ", hst));


        //SortedSet
        var sst = new SortedSet<int>() { 3, 5, 1, 2, 4, 1, 2 };
        Console.WriteLine("sstの要素数は{0}です", sst.Count);
        Console.WriteLine("sst2:[{0}]", string.Join(" ", sst));
    }
}

出力結果

hstの要素数は5です
hst:[3 5 1 2 4]
sstの要素数は5です
sst2:[1 2 3 4 5]

Addメソッドによる要素の追加

HashSetやSortedSetに要素を追加するには、Addメソッドを使用します。Addメソッドの引数は追加する要素の値です。戻り値はbool型でオブジェクトに要素が追加された場合はtrue、要素がすでに存在していた場合はfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst = new HashSet<int>() { 1, 3, 5 };
        Console.WriteLine("hstに2を追加します.結果:{0}", hst.Add(2));
        Console.WriteLine("hstに3を追加します.結果:{0}", hst.Add(3));
        Console.WriteLine("hst:[{0}]", string.Join(" ", hst));


        //SortedSet
        var sst = new SortedSet<int>() { 1, 3, 5 };
        Console.WriteLine("sstに2を追加します.結果:{0}", sst.Add(2));
        Console.WriteLine("sstに3を追加します.結果:{0}", sst.Add(3));
        Console.Write("hst:[{0}]", string.Join(" ", sst));
    }
}

出力結果

hstに2を追加します.結果:True
hstに3を追加します.結果:False
hst:[1 3 5 2]
sstに2を追加します.結果:True
sstに3を追加します.結果:False
hst:[1 2 3 5]

上記コードでは10~11行目と17~18行目でAddメソッドが使われています。2を追加している10,17行目ではAddメソッドはtrueを返していますが、11,18行目では3はすでにオブジェクトに存在しているのでAddメソッドはfalseを返しています。

Clearメソッドで要素をすべて削除する

ClearメソッドでHashSetやSortedSetオブジェクトのすべての要素を削除します。Clearメソッドに、引数、戻り値はありません。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst = new HashSet<int>() { 1, 3, 5 };
        Console.WriteLine("Clear前hst:[{0}]", string.Join(" ", hst));
        hst.Clear();
        Console.WriteLine("Clear後hst:[{0}]", string.Join(" ", hst));


        //SortedSet
        var sst = new SortedSet<int>() { 1, 3, 5 };
        Console.WriteLine("Clear前sst:[{0}]", string.Join(" ", sst));
        sst.Clear();
        Console.WriteLine("Clear後sst:[{0}]", string.Join(" ", sst));
    }
}

出力結果

Clear前hst:[1 3 5]
Clear後hst:[]
Clear前sst:[1 3 5]
Clear後sst:[]

Removeメソッドで指定した値を持つ要素を削除する

RemoveメソッドでHashSetやSortedSetオブジェクトの指定した値を持つ要素を削除できます。Removeメソッドの引数は削除する値です。戻り値はbool型で正常に削除されればtrue、それ以外の場合はfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst = new HashSet<int>() { 1, 3, 5 };
        Console.WriteLine("hstから2を削除します.結果:{0}", hst.Remove(2));
        Console.WriteLine("hstから3を削除します.結果:{0}", hst.Remove(3));
        Console.WriteLine("hst:[{0}]", string.Join(" ", hst));


        //SortedSet
        var sst = new SortedSet<int>() { 1, 3, 5 };
        Console.WriteLine("sstから2を削除します.結果:{0}", sst.Remove(2));
        Console.WriteLine("sstから3を削除します.結果:{0}", sst.Remove(3));
        Console.Write("hst:[{0}]", string.Join(" ", sst));
    }
}

出力結果

hstから2を削除します.結果:False
hstから3を削除します.結果:True
hst:[1 5]
sstから2を削除します.結果:False
sstから3を削除します.結果:True
hst:[1 5]

上記コードでは、10~11行目および17~18行目でRemoveメソッドを使用しています。それぞれのオブジェクトには、2は含まれていないので削除できないので10,17行目のRemoveメソッドの戻り値はfalse、3は含まれているので正常に削除できるので11,18行目のRemoveメソッドではtrueが返されています。

RemoveWhereメソッドで指定した条件に一致するすべての要素を削除する

RemoveWhereメソッドでHashSetやSortedSetオブジェクトの指定した条件に一致するすべての要素を削除することができます。引数は、条件を指定するPredicate<T>デリゲートです。戻り値はint型で削除された要素数です。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        int rm;

        //HashSet
        var hst = new HashSet<int>() { 4, 1, 3, 8, 5, 6 };
        Console.WriteLine("RemoveWhere前hst:[{0}]", string.Join(" ", hst));
        rm = hst.RemoveWhere(x => x % 2 == 0);
        Console.WriteLine("RemoveWhere後hst:[{0}], 削除された数:{1}", string.Join(" ", hst), rm);


        //SortedSet
        var sst = new SortedSet<int>() { 4, 1, 3, 8, 5, 6 };
        Console.WriteLine("RemoveWhere前sst:[{0}]", string.Join(" ", sst));
        rm = sst.RemoveWhere(x => x % 2 == 0);
        Console.WriteLine("RemoveWhere後sst:[{0}], 削除された数:{1}", string.Join(" ", sst), rm);
    }
}

出力結果

RemoveWhere前hst:[4 1 3 8 5 6]
RemoveWhere後hst:[1 3 5], 削除された数:3
RemoveWhere前sst:[1 3 4 5 6 8]
RemoveWhere後sst:[1 3 5], 削除された数:3

上記コードでは、13行目と20行目でRemoveWhereメソッドを使用しています。引数のPredicateデリゲートはラムダ式で表されており、削除する条件は「2で割った余りが0」つまり偶数の要素です。偶数の要素は3つあるのでRemoveWhereメソッドの戻り値は3になります。

Containsメソッドで指定した値を持つ要素の有無を調べる

ContainsメソッドでHashSetやSortedSetオブジェクトに指定した値を持つ要素の有無を調べることができます。引数は、有無を調べる値です。戻り値はbool型で、その値がオブジェクトに含まれていればtrue、そうでない場合にはfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        int val1 = 2;
        int val2 = 3;

        //HashSet
        var hst = new HashSet<int>() { 4, 1, 3, 8, 5, 6 };
        Console.WriteLine("hstに{0}が含まれているかを調べます.結果:{1}", val1, hst.Contains(val1));
        Console.WriteLine("hstに{0}が含まれているかを調べます.結果:{1}", val2, hst.Contains(val2));


        //SortedSet
        var sst = new SortedSet<int>() { 4, 1, 3, 8, 5, 6 };
        Console.WriteLine("sstに{0}が含まれているかを調べます.結果:{1}", val1, sst.Contains(val1));
        Console.WriteLine("sstに{0}が含まれているかを調べます.結果:{1}", val2, sst.Contains(val2));
    }
}

出力結果

hstに2が含まれているかを調べます.結果:False
hstに3が含まれているかを調べます.結果:True
sstに2が含まれているかを調べます.結果:False
sstに3が含まれているかを調べます.結果:True

HashSetとSortedSetの集合の演算メソッド

ここではHashSetとSortedSetの集合演算をするメソッドを解説します。

UnionWithで和集合を求める

UnionWithメソッドでは和集合を求めることができます。UnionWithメソッドの引数は一つで、和集合を求める対象となるコレクションのオブジェクトを指定します。よって引数には配列やListを指定することができます。また、このメソッドに戻り値はありません。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8 };
        var hst2 = new HashSet<int>() { 3, 5, 2, 4 };
        hst2.UnionWith(hst1);
        Console.WriteLine("hst1とhst2の和集合:[{0}]",string.Join(" ",hst2));


        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8 };
        var sst2 = new SortedSet<int>() { 3, 5, 2, 4 }; 
        sst2.UnionWith(sst1);
        Console.WriteLine("sst1とsst2の和集合:[{0}]", string.Join(" ", sst2));
    }
}

出力結果

hst1とhst2の和集合:[3 5 2 4 1 8]
sst1とsst2の和集合:[1 2 3 4 5 8]

上記11行目と18行目でUnionWithを使っています。このときにhst2やsst2は元の値を保持せず、和集合に書き換えられますので注意してください。

IntersectWithで積集合を求める

IntersectWithメソッドでは積集合を求めることができます。基本的な使い方はUnionWithと同じです。IntersectWithメソッドの引数は一つで、積集合を求める対象となるコレクションのオブジェクトを指定します。よって引数には配列やListを指定することができます。また、このメソッドに戻り値はありません。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8 };
        var hst2 = new HashSet<int>() { 3, 5, 2, 4 };
        hst2.IntersectWith(hst1);
        Console.WriteLine("hst1とhst2の積集合:[{0}]",string.Join(" ",hst2));


        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8 };
        var sst2 = new SortedSet<int>() { 3, 5, 2, 4 }; 
        sst2.IntersectWith(sst1);
        Console.WriteLine("sst1とsst2の積集合:[{0}]", string.Join(" ", sst2));
    }
}

出力結果

hst1とhst2の積集合:[3 4]
sst1とsst2の積集合:[3 4]

上記11行目と18行目でIntersectWithを使っています。このときにhst2やsst2は元の値を保持せず、積集合に書き換えられますので注意してください。

ExceptWithで差集合を求める

ExceptWithメソッドでは差集合を求めることができます。基本的な使い方はUnionWithと同じです。ExceptWithメソッドの引数は一つで、差集合を求める対象となるコレクションのオブジェクトを指定します。よって引数には配列やListを指定することができます。また、このメソッドに戻り値はありません。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8 };
        var hst2 = new HashSet<int>() { 3, 5, 2, 4 };
        hst2.ExceptWith(hst1);
        Console.WriteLine("hst1とhst2の差集合:[{0}]",string.Join(" ",hst2));


        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8 };
        var sst2 = new SortedSet<int>() { 3, 5, 2, 4 }; 
        sst2.ExceptWith(sst1);
        Console.WriteLine("sst1とsst2の差集合:[{0}]", string.Join(" ", sst2));
    }
}

出力結果

hst1とhst2の差集合:[5 2]
sst1とsst2の差集合:[2 5]

上記11行目と18行目でExceptWithを使っています。このときにhst2やsst2は元の値を保持せず、積集合に書き換えられますので注意してください。

SymmetricExceptWithで対称差集合を求める

集合Aと集合Bの和から集合Aと集合Bの積を引いたものが、集合Aと集合Bの対称差集合になります。

SymmetricExceptWithメソッドでは対称差集合を求めることができます。基本的な使い方はUnionWithと同じです。SymmetricExceptWithメソッドの引数は一つで、対称差集合を求める対象となるコレクションのオブジェクトを指定します。よって引数には配列やListを指定することができます。また、このメソッドに戻り値はありません。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8 };
        var hst2 = new HashSet<int>() { 3, 5, 2, 4 };
        hst2.SymmetricExceptWith(hst1);
        Console.WriteLine("hst1とhst2の対称差集合:[{0}]",string.Join(" ",hst2));


        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8 };
        var sst2 = new SortedSet<int>() { 3, 5, 2, 4 }; 
        sst2.SymmetricExceptWith(sst1);
        Console.WriteLine("sst1とsst2の対称差集合:[{0}]", string.Join(" ", sst2));
    }
}

出力結果

hst1とhst2の対称差集合:[8 5 2 1]
sst1とsst2の対称差集合:[1 2 5 8]

上記11行目と18行目でSymmetricExceptWithを使っています。このときにhst2やsst2は元の値を保持せず、対称差集合に書き換えられますので注意してください。

IsSubsetOfで部分集合(サブセット)かどうかを調べる

A.IsSubsetOf(B)で集合Aが集合Bの部分集合(サブセット)かどうかを調べることができます。「AがBの部分集合である」とは集合Aの要素がすべて集合Bに含まれている状態のことです。引数にはHashSetやSortedSetだけでなく、配列やListなどのコレクションを指定することができます。また、このメソッドの戻り値はbool型で、AがBの部分集合であればtrue,そうでなければfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var hst2 = new HashSet<int>() { 2, 4 };
        var hst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("hst2がhst1の部分集合かどうかの判定結果:{0}", hst2.IsSubsetOf(hst1));
        Console.WriteLine("hst1がhst2の部分集合かどうかの判定結果:{0}", hst1.IsSubsetOf(hst2));
        Console.WriteLine("hst1がhst3の部分集合かどうかの判定結果:{0}", hst1.IsSubsetOf(hst3));

        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var sst2 = new SortedSet<int>() { 2, 4 };
        var sst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("sst2がsst1の部分集合かどうかの判定結果:{0}", sst2.IsSubsetOf(sst1));
        Console.WriteLine("sst1がsst2の部分集合かどうかの判定結果:{0}", sst1.IsSubsetOf(sst2));
        Console.WriteLine("sst1がsst3の部分集合かどうかの判定結果:{0}", sst1.IsSubsetOf(sst3));
    }
}

出力結果

hst2がhst1の部分集合かどうかの判定結果:True
hst1がhst2の部分集合かどうかの判定結果:False
hst1がhst3の部分集合かどうかの判定結果:True
sst2がsst1の部分集合かどうかの判定結果:True
sst1がsst2の部分集合かどうかの判定結果:False
sst1がsst3の部分集合かどうかの判定結果:True

上記コードでは、hst2がhst1の部分集合であることがわかります。しかしその逆でhst1はhst2の部分集合ではありません。またhst1とhst3は同じ集合なので、hst1はhst3の部分集合と言えます。sst1,sst2,sst3についても同じです。

IsProperSubsetOfで真部分集合かどうかを調べる

A.IsProperSubsetOf(B)で集合Aが集合Bの真部分集合(サブセット)かどうかを調べることができます。「AがBの真部分集合である」とは集合Aの要素がすべて集合Bに含まれていて、かつA≠Bの状態のことです。つまりAはBに含まれているがAのほうが小さな集合という意味です。引数にはHashSetやSortedSetだけでなく、配列やListなどのコレクションを指定することができます。また、このメソッドの戻り値はbool型で、AがBの真部分集合であればtrue,そうでなければfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var hst2 = new HashSet<int>() { 2, 4 };
        var hst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("hst2がhst1の真部分集合かどうかの判定結果:{0}", hst2.IsProperSubsetOf(hst1));
        Console.WriteLine("hst1がhst3の真部分集合かどうかの判定結果:{0}", hst1.IsProperSubsetOf(hst3));

        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var sst2 = new SortedSet<int>() { 2, 4 };
        var sst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("sst2がsst1の真部分集合かどうかの判定結果:{0}", sst2.IsProperSubsetOf(sst1));
        Console.WriteLine("sst1がsst3の真部分集合かどうかの判定結果:{0}", sst1.IsProperSubsetOf(sst3));
    }
}

出力結果

hst2がhst1の真部分集合かどうかの判定結果:True
hst1がhst3の真部分集合かどうかの判定結果:False
sst2がsst1の真部分集合かどうかの判定結果:True
sst1がsst3の真部分集合かどうかの判定結果:False

上記の例では、hst2はhst1の真部分集合ですが、hst1とhst3は同じなので、hst1はhst3の真部分集合ではありません。sst1,sst2,sst3についても同じです。

IsSupersetOfで上位集合かどうかを調べる

A.IsSupersetOf(B)で集合Aが集合Bの上位集合(スーパーセット)であるかを調べることができます。「AがBの上位集合である」とは集合Aの要素に集合Bの要素がすべて含まれている状態のことです。引数にはHashSetやSortedSetだけでなく、配列やListなどのコレクションを指定することができます。また、このメソッドの戻り値はbool型で、AがBの上位集合であればtrue,そうでなければfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var hst2 = new HashSet<int>() { 2, 4 };
        var hst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("hst2がhst1の上位集合かどうかの判定結果:{0}", hst2.IsSupersetOf(hst1));
        Console.WriteLine("hst1がhst2の上位集合かどうかの判定結果:{0}", hst1.IsSupersetOf(hst2));
        Console.WriteLine("hst1がhst3の上位集合かどうかの判定結果:{0}", hst1.IsSupersetOf(hst3));

        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var sst2 = new SortedSet<int>() { 2, 4 };
        var sst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("sst2がsst1の上位集合かどうかの判定結果:{0}", sst2.IsSupersetOf(sst1));
        Console.WriteLine("sst1がsst2の上位集合かどうかの判定結果:{0}", sst1.IsSupersetOf(sst2));
        Console.WriteLine("sst1がsst3の上位集合かどうかの判定結果:{0}", sst1.IsSupersetOf(sst3));
    }
}

出力結果

hst2がhst1の上位集合かどうかの判定結果:False
hst1がhst2の上位集合かどうかの判定結果:True
hst1がhst3の上位集合かどうかの判定結果:True
sst2がsst1の上位集合かどうかの判定結果:False
sst1がsst2の上位集合かどうかの判定結果:True
sst1がsst3の上位集合かどうかの判定結果:True

上記の例では、hst1はhst2の上位集合になります。hst1とhst3は同じなので、hst1はhst3の上位集合になります。sst1,2,3も同様です。

IsProperSupersetOfで真上位集合かどうかを調べる

A.IsProperSupersetOf(B)で集合Aが集合Bの真上位集合(スーパーセット)であるかを調べることができます。「AがBの真上位集合である」とは集合Aの要素に集合Bの要素がすべて含まれていて、かつA≠Bの状態のことです。引数にはHashSetやSortedSetだけでなく、配列やListなどのコレクションを指定することができます。また、このメソッドの戻り値はbool型で、AがBの真上位集合であればtrue,そうでなければfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var hst2 = new HashSet<int>() { 2, 4 };
        var hst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("hst2がhst1の真上位集合かどうかの判定結果:{0}", hst2.IsProperSupersetOf(hst1));
        Console.WriteLine("hst1がhst2の真上位集合かどうかの判定結果:{0}", hst1.IsProperSupersetOf(hst2));
        Console.WriteLine("hst1がhst3の真上位集合かどうかの判定結果:{0}", hst1.IsProperSupersetOf(hst3));

        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        var sst2 = new SortedSet<int>() { 2, 4 };
        var sst3 = new HashSet<int>() { 4, 1, 3, 8, 3, 5, 2 };
        Console.WriteLine("sst2がsst1の真上位集合かどうかの判定結果:{0}", sst2.IsProperSupersetOf(sst1));
        Console.WriteLine("sst1がsst2の真上位集合かどうかの判定結果:{0}", sst1.IsProperSupersetOf(sst2));
        Console.WriteLine("sst1がsst3の真上位集合かどうかの判定結果:{0}", sst1.IsProperSupersetOf(sst3));
    }
}

出力結果

hst2がhst1の真上位集合かどうかの判定結果:False
hst1がhst2の真上位集合かどうかの判定結果:True
hst1がhst3の真上位集合かどうかの判定結果:False
sst2がsst1の真上位集合かどうかの判定結果:False
sst1がsst2の真上位集合かどうかの判定結果:True
sst1がsst3の真上位集合かどうかの判定結果:False

上記の例では、hst1はhst2の真上位集合になります。hst1とhst3は同じなので、hst1はhst3の真上位集合にはなりません。sst1,2,3も同様です。

Overlapsで共通の要素が存在するかを調べる

A.Overlaps(B)で集合Aと集合Bが共通の値の要素を持つかどうかを調べることができます。引数にはHashSetやSortedSetだけでなく、配列やListなどのコレクションを指定することができます。また、このメソッドの戻り値はbool型で、AとBが共通要素を持てばtrue,そうでなければfalseを返します。

コード

using System;
using System.Collections.Generic;

internal class Program
{
    static void Main(string[] args)
    {
        //HashSet
        var hst1 = new HashSet<int>() { 4, 1, 3, 2 };
        var hst2 = new HashSet<int>() { 2, 4, 9, 8 };
        var hst3 = new HashSet<int>() { 10, 14, 11, 8 };
        Console.WriteLine("hst1とhst2と共通要素の有無の判定結果:{0}", hst1.Overlaps(hst2));
        Console.WriteLine("hst2とhst3と共通要素の有無の判定結果:{0}", hst2.Overlaps(hst3));
        Console.WriteLine("hst1とhst3と共通要素の有無の判定結果:{0}", hst1.Overlaps(hst3));

        //SortedSet
        var sst1 = new SortedSet<int>() { 4, 1, 3, 2 }; 
        var sst2 = new SortedSet<int>() { 2, 4, 9, 8 };
        var sst3 = new HashSet<int>() { 10, 14, 11, 8 };
        Console.WriteLine("sst1とsst2と共通要素の有無の判定結果:{0}", sst1.Overlaps(sst2));
        Console.WriteLine("sst2とsst3と共通要素の有無の判定結果:{0}", sst2.Overlaps(sst3));
        Console.WriteLine("sst1とsst3と共通要素の有無の判定結果:{0}", sst1.Overlaps(sst3));
    }
}

出力結果

hst1とhst2と共通要素の有無の判定結果:True
hst2とhst3と共通要素の有無の判定結果:True
hst1とhst3と共通要素の有無の判定結果:False
sst1とsst2と共通要素の有無の判定結果:True
sst2とsst3と共通要素の有無の判定結果:True
sst1とsst3と共通要素の有無の判定結果:False

上記コードでは、hst1とhst2は共通要素を持ち、hst2とhst3も共通要素を持っていますが、hst1とhst3は共通要素を持っていません。sst1,2,3も同様です。

終わりに

今回はC#$による集合演算について解説しました。知っていると便利な場面もありますので、ぜひ覚えておきましょう。

ABOUT ME
しかすけ
日々是好日。何とか何とか生きてます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です