如何在List中存储整数对? 我知道我可以为他们上课:
class Pair
{
int i1,i2;
}
但是,如果我这样做,我将无法使用Contains
函数来检查给定对是否在列表中。我怎么能这样做,所以我可以轻松地将整数存储在List中,并检查一对整数是否已经存在?我不能使用表,因为不知道会有多少对。
修改:
忘了添加:
在我的程序中,对(x,y)和(y,x)将被视为等于。
修改
(x,y)和(y,x)在检查列表中是否Point
时是等于,但x
和y
无法交换,因为x
和{ {1}}代表两点之间的连接(整数是点的id,而不是我不能使用任何引用等......)。当我检查y
是否包含连接时,如果它是(x,y)或(y,x)并不重要,但稍后我会需要这些信息。
答案 0 :(得分:41)
如果您使用的是.NET 4.0,则可以使用
中的Tuple
类
var tuple = new Tuple<int, int>(17, 42);
var otherTuple = Tuple.Create(17, 42);
和
var list = new List<Tuple<int, int>>();
请注意,如果您使用Tuple<int, int>
的路线,则需要创建IEqualityComparer<Tuple<TFirst, TSecond>>
的自定义实施,以反映(x, y)
被视为等于{{1}的平等规则}}。然后,您必须将此比较器的实例传递给(y, x)
(此处List<T>.Contains(T, IEqualityComparer<T>)
为T
)。
Tuple<int, int>
否则,如果您不能或不想使用class TupleAsUnorderedPairComparer : IEqualityComparer<Tuple<TFirst, TSecond>> {
public bool Equals(Tuple<TFirst, TSecond> x, Tuple<TFirst, TSecond> y) {
if(Object.ReferenceEquals(x, y)) {
return true;
}
if(x == null || y == null) {
return false;
}
return x.Item1 == y.Item1 && x.Item2 == y.Item2 ||
x.Item1 == y.Item2 && x.Item2 == y.Item1;
}
public int GetHashCode(Tuple<TFirst, TSecond> x) {
if(x == null) {
return 0;
}
return x.Item1.GetHashCode() ^ x.Item2.GetHashCode();
}
}
,那么您需要为Tuple
课程实施IEqualityComparer<Pair>
或覆盖Pair
, Object.Equals
。
Object.GetHashCode
和
class Pair {
public int First { get; private set; }
public int Second { get; private set; }
public Pair(int first, int second) {
this.First = first;
this.Second = second;
}
public override bool Equals(object obj) {
if(Object.ReferenceEquals(this, obj)) {
return true;
}
Pair instance = obj as Pair;
if(instance == null) {
return false;
}
return this.First == instance.First && this.Second == instance.Second ||
this.First == instance.Second && this.Second == instance.First;
}
public override int GetHashCode() {
return this.First.GetHashCode() ^ this.Second.GetHashCode();
}
}
如果您使用
class PairEqualityComparer : IEqualityComparer<Pair> {
// details elided
}
然后它将使用list.Contains(pair);
和Equals
,但如果您使用
GetHashCode
然后它将使用list.Contains(pair, new PairEqualityComparer);
和PairEqualityComparer.Equals
。请注意,这些可能与PairEqualityComparer.GetHashCode
和Object.Equals
的实现不同。
最后,如果您经常进行遏制测试,那么Object.GetHashCode
不是您最好的选择;您应该使用专为此目的设计的课程,例如List
。
答案 1 :(得分:2)
上课是你最好的选择。如果您已经开始使用Contains
方法,则必须在Pair类中实现IComparable
接口。这将允许您为这对整数建立“相等”意味着什么。
最简单的方法是创建类,然后在List<T>
对象上创建和扩展方法。
public static bool ContainsIntegers(this List<Pair> targetList, Pair comparer) {
foreach(Pair pair in targetList)
{
if(pair.i1 == comparer.i1 && pair.i2 == comparer.i2) return true;
}
return false;
}
答案 2 :(得分:2)
另一种方法是使用List<ulong>
,通过将最大数字放在高32位而另一个数字放在低32位来填充它:
ulong MakeEntry(int i1, int i2)
{
ulong hi = (ulong)Math.Max(i1, i2);
ulong lo = (ulong)Math.Min(i1, i2);
return (hi << 32) | lo;
}
List<ulong> items = new List<ulong>();
void DoSomething()
{
// get numbers i1 and i2
// and add to the list
items.Add(MakeEntry(i1, i2));
// test to see if the pair is in the list
if (items.Contains(MakeEntry(i1, i2)))
{
// do whatever
}
}