我有以下数据类型:
ISet<IEnumerable<Foo>>
所以,我需要能够创建一系列序列。例如。这没关系:
ABC,AC,A
但这不是(因为“AB”在这里重复“):
AB,A,ABC,BCA,AB
但是,为了做到这一点 - 为了使“set”不包含重复项,我需要将IEnumerable
包装成某种其他数据类型:
ISet<Seq>
//where
Seq : IEnumerable<Foo>, IEquatable<Seq>
因此,我将能够比较两个序列,并为Set数据结构提供一种消除重复的方法。
我的问题是:是否存在允许比较序列的快速数据结构?我想在某种程度上创建Seq
或添加两个时,会计算某种累积值。
换句话说,是否可以以这样的方式实现Seq:
var seq1 = new Seq( IList<Foo> );
var seq2 = new Seq( IList<Foo> )
seq1.equals(seq2) // O(1)
感谢。
答案 0 :(得分:2)
我在下面提供了一个实现序列。有几点需要注意:
IEnumerable<T>
每次枚举时返回相同的项目,并且这些项目在此对象的范围内不会发生变异时,此方法才有效。equals方法首先比较哈希码。如果哈希码不同,则对象不可能相等(如果哈希码在序列中的所有对象上正确实现,并且没有任何变异)。只要你的碰撞率很低,并且通常比较实际上不相等的项目,这意味着等于检查通常不会超过该哈希码检查。如果他们这样做,则需要迭代序列(没有办法解决)。因为等于可能平均为O(1),即使最坏的情况仍为O(n)。
public class Foo:IEnumerable { 私有IEnumerable序列;
private int? myHashCode = null;
public Foo(IEnumerable<T> sequence)
{
this.sequence = sequence;
}
public IEnumerator<T> GetEnumerator()
{
return sequence.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return sequence.GetEnumerator();
}
public override bool Equals(object obj)
{
Foo<T> other = obj as Foo<T>;
if(other == null)
return false;
//if the hash codes are different we don't need to bother doing a deep equals check
//the hash code is cached, so it's fast.
if (GetHashCode() != obj.GetHashCode())
return false;
return Enumerable.SequenceEqual(sequence, other.sequence);
}
public override int GetHashCode()
{
//note that the hash code is cached, so the underlying sequence
//needs to not change.
return myHashCode ?? populateHashCode();
}
private int populateHashCode()
{
int somePrimeNumber = 37;
myHashCode = 1;
foreach (T item in sequence)
{
myHashCode = (myHashCode * somePrimeNumber) + item.GetHashCode();
}
return myHashCode.Value;
}
}
答案 1 :(得分:1)
O(1)实质上意味着不允许比较元素的值。如果您可以将序列表示为不可变对象的列表(添加缓存以便所有实例都没有重复),您可以实现它,因为您只需要比较第一个元素 - 类似于字符串实习的工作方式。
Insert必须搜索“current”+“with this next”元素的所有元素实例。某种字典可能是合理的方法......
编辑:我认为它只是试图提出suffix tree。