如何在List中存储数字对并仍然能够对它们进行排序并根据第一个元素进行二进制搜索?

时间:2014-01-26 19:19:45

标签: c# .net data-structures

基本上我需要能够根据第一个数字进行排序和二分搜索,但我还需要将第二个数字与每个元素相关联。

我不能做键值对,因为键不一定是唯一的。但我觉得这必须足够普遍,以保证某种内置的解决方案,如Pairs或其他东西,只是我不知道如何使它们仍然基于一对中的第一个int进行排序。

有什么想法吗?

编辑:

根据你的建议,我用脸推了过去,然后做了这个:

public class Pair
{
    int first;
    int second;
    public Pair(int x, int y)
    {
        first = x;
        second = y;
    }
    public int CompareTo(Pair compair)
    {
        if (compair != null)
        {
            return this.first.CompareTo(compair.first);
        }
        else
            return 1;
    }
}

我真的希望有一条线和内置的东西,速度如果我需要在某种采访中做到这一点,但我想这是有效的。

3 个答案:

答案 0 :(得分:1)

创建包含2个点的类,实现IComparable

答案 1 :(得分:1)

如前所述,您已经开始创建一个Pair类,可以比较它。但是这个要求引发了一个动作:

  

我不能做键值对,因为键不一定   唯一的。

因此,这告诉我你可以为first设置多个具有相同值的对。您可以按原样申报Pair课程,然后根据该密钥使用SortedDictionary。它们将在输入时进行排序,您可以执行O(1)哈希表查找:

var input = new[]{
    new Pair(1, 1),
    new Pair(5, 2),
    new Pair(1, 2),
    new Pair(2, 1),
    new Pair(7, 4),
    new Pair(3, 1),
    new Pair(7, 2)
};

SortedDictionary<int, List<Pair>> pairs = 
    new SortedDictionary<int, List<Pair>>();

foreach(var pair in input)
{
    if (!pairs.ContainsKey(pair.First))
        pairs.Add(pair.First, new List<Pair>());

    pairs[pair.First].Add(pair);
}

为了完整性,这里是我声明的Pair类:

public class Pair : IComparable<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 int CompareTo(Pair other)
    {
        if (other != null)
            return this.First.CompareTo(other.First);
        else
            return 1;
    }
}

这可能是我要去的路线(或多或少取决于具体要求)。你还说:

  

我真的希望有一条线和内置的东西

嗯,最接近“内置”我可以想到使用Tuple<int, int>并使用一点LINQ。为了清楚起见,我将它写成两行,但它可以很容易地组合成一行:

var input = new[]{
    Tuple.Create(1, 1),
    Tuple.Create(5, 2),
    Tuple.Create(1, 2),
    Tuple.Create(2, 1),
    Tuple.Create(7, 4),
    Tuple.Create(3, 1),
    Tuple.Create(7, 2)
};

var unsortedDictionary = input
    .GroupBy(p => p.Item1)
    .ToDictionary(g => g.Key, g => g.Select(i => i));

var sortedDictionary = 
    new SortedDictionary<int, IEnumerable<Tuple<int, int>>>(unsortedDictionary);

我不确定这是否更好。那里有嵌套元组有点奇怪。如果需要,此时元组变为冗余,因为字典的“Key”与每个值都重复,因此您可以将“Key”与一组“Second”值相关联(每对的后半部分) ):

var unsortedDictionary = input
    .GroupBy(p => p.Item1)
    .ToDictionary(g => g.Key, g => g.Select(i => i.Item2));

var sortedDictionary = 
    new SortedDictionary<int, IEnumerable<int>>(unsortedDictionary);

至于在求职面试中使用速度,你可能需要小心。在这里混合类型非常容易(例如,当你只想传递IEnumerable<int>时,很容易传递int并且错误地声明字典的类型等等)

答案 2 :(得分:-1)

List<Tuple<int,int>> 

然后第一个数字不必是唯一的