在列表中存储一对int

时间:2010-12-04 16:47:50

标签: c# list integer

如何在List中存储整数对? 我知道我可以为他们上课:

class Pair  
{
    int i1,i2;
}

但是,如果我这样做,我将无法使用Contains函数来检查给定对是否在列表中。我怎么能这样做,所以我可以轻松地将整数存储在List中,并检查一对整数是否已经存在?我不能使用表,因为不知道会有多少对。

修改:
忘了添加: 在我的程序中,对(x,y)和(y,x)将被视为等于。

修改
(x,y)和(y,x)在检查列表中是否Point时是等于,但xy无法交换,因为x和{ {1}}代表两点之间的连接(整数是点的id,而不是我不能使用任何引用等......)。当我检查y是否包含连接时,如果它是(x,y)或(y,x)并不重要,但稍后我会需要这些信息。

3 个答案:

答案 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>或覆盖PairObject.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.GetHashCodeObject.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
    }
}