何らかの種類があると仮定するとIEnumerable<int>
、次のことができます。
int count = stream.Distinct().Count();
セット メンバーシップが GetHashCode() に基づいていることを正しく理解していますか?
そうではありません。a のメンバーシップは、と の等価性チェックHashSet
の組み合わせに基づいています。GetHashCode
一般に、2 つのオブジェクトが同じハッシュコードを持つことはできますが、等しくはなりません。しかし、int
それは起こり得ません。
そして、Int32 のハッシュ コードは数値そのものですか?
はい、そうです。
CPU 効率またはメモリ効率を高める方法はありますか?
int が狭い範囲にあることがわかっている場合は、ビットマップを使用して見たものを効率的に保存できます。たとえば、範囲が 1,000,000 の場合、見た int を 1,000,000 ビットで格納できます。インデックス n で 1 に設定されたビットは、整数 n を見たことを意味します。これを実装する 1 つの方法を示すサンプル コードを次に示します。
void Main()
{
int max = 1000000;
IEnumerable<int> stream = GetStream(max);
int count = DistinctCount(stream, max);
int count2 = stream.Distinct().Count();
Debug.Assert(count == count2);
}
int DistinctCount(IEnumerable<int> stream, int max)
{
int[] seen = new int[max / 32];
foreach (int x in stream)
{
seen[x / 32] |= 1 << (x % 32);
}
int count = 0;
foreach (uint s in seen)
{
uint t = s;
while (t > 0)
{
if (t % 2 == 1) { count++; }
t /= 2;
}
}
return count;
}
IEnumerable<int> GetStream(int max)
{
List<int> stream = new List<int>();
Random random = new Random();
for (int i = 0; i < 2000000; ++i)
{
stream.Add(random.Next(max));
}
return stream;
}