C# 计算列表中的重复数字

C# 计算列表中的重复数字,c#,list,C#,List,我有一份清单: int list = { 1,1,2,3,4,4,5,7,7,7,10}; 现在我需要做一个程序来计算双倍数。如果前面的数字相同,则该数字是双精度的。我希望你能理解。所以1是双打,4是双打,我们在7,7,7中得到了2个双打 以下是LINQ中的一个解决方案: var doubles = list.Skip(1) .Where((number, index) => list[index] == number); 这将通过跳过列表的第一个成

我有一份清单:

int list = { 1,1,2,3,4,4,5,7,7,7,10};

现在我需要做一个程序来计算双倍数。如果前面的数字相同,则该数字是双精度的。我希望你能理解。所以1是双打,4是双打,我们在7,7,7中得到了2个双打

以下是LINQ中的一个解决方案:

var doubles = list.Skip(1)
                  .Where((number, index) => list[index] == number);

这将通过跳过列表的第一个成员来创建另一个序列,然后从两个序列中查找具有相同索引和相同值的元素。它将以线性时间运行,但这仅仅是因为列表提供了按索引访问的
O(1)

类似的功能可能会起作用:

list.GroupBy (l => l).Where (l => l.Count () > 1).SelectMany (l => l).Distinct();
编辑:

上面的代码没有得到OP想要的结果。以下是一个经过编辑的版本,其灵感来源于Ani下面优雅的解决方案:)


这是一种相对简单的方法,只在序列上迭代一次,并且适用于任何序列(不仅仅是列表):


每个人似乎都在试图找到好的方法,所以这里有一个非常糟糕的方法:

List<int> doubles = new List<int>();
Dictionary<int, bool> seenBefore = new Dictionary<int, bool>();

foreach(int i in list)
{
    try
    {
        seenBefore.Add(i, true);
    }
    catch (ArgumentException)
    {
        doubles.Add(i);
    }
}

return doubles;
List doubles=new List();
字典seenBefore=新字典();
foreach(列表中的int i)
{
尝试
{
参见上文。添加(i,true);
}
捕获(异常)
{
双倍。加上(i);
}
}
双打;

请不要那样做。

给你,答案是c:)

int[]intarray=newint[]{1,1,2,3,4,4,5,7,7,10};
int-previousnumber=-1;
列表双位数=新列表();
for(int i=0;i
一个(可能)比使用Linq性能更好的示例,尽管可以说不那么优雅:

for (int i = 1; i < list.Count; i++)
    if (list[i] == list[i - 1])
        doubles.Add(list[i]);
for(int i=1;i
您可以这样做:

list.GroupBy(i => i).Where(g => g.Count() > 1).SelectMany(g => g.Skip(1))
这有点像@KJN的答案,只是我认为它更好地表达了问题中的“doubles”和“two doubles”子句:

  • 将所有整数分组在一起
  • 只对多次出现的内容感兴趣(
    g.Count()>1
  • 选择一个平展的“双精度”列表,即第一个之后的双精度(
    g.Skip(1)

  • PS:我们在这里假设,
    GroupBy
    不会首先对列表进行排序,如果是,排序不会受到预排序列表的负面影响…

    您能提供更多关于为什么/如何排序的信息吗?感觉像是一个家庭作业/面试问题。这将是非常简单的解决办法,只是使用一个循环,并比较以前的电流和存储/重置,如果找到匹配-只是一个额外的逻辑位停止7被计数3次。如果你想用linq或其他什么来解决这个问题,那就更有趣了。你说的“使用副作用”是什么意思?@Lasse:说得对。嗯,我改变了计划。等一下,我会把副作用版本放回去:)A绝对+1。答案简洁、正确(未经测试,但我承担风险),非常聪明,并且正确地解释了为什么它以线性时间运行。想象一下,将其复制为家庭作业答案,然后向全班(和老师)解释。。。姆瓦哈哈哈桑克斯。我不确定我是否会因为发布了一个糟糕的答案而得票下降,还是因为说答案不好而得票上升。:-)+1除了异常之外,这不是一个完全不好的非Linq答案-您可以使用ContainsKey或TryGetValue来避免异常,这样就可以了。是的,但我只是使用字典,以便引发异常。:-)
    HashSet
    在这里非常有用。我考虑过HashSet,但它没有抛出我想要的异常:P
    IEnumerable<int> sequence = ...;
    IEnumerable<int> result = sequence.SelectConsecutive((x, y) => new { x, y })
                                      .Where(z => z.x == z.y);
    
    List<int> doubles = new List<int>();
    Dictionary<int, bool> seenBefore = new Dictionary<int, bool>();
    
    foreach(int i in list)
    {
        try
        {
            seenBefore.Add(i, true);
        }
        catch (ArgumentException)
        {
            doubles.Add(i);
        }
    }
    
    return doubles;
    
    int[] intarray = new int[] { 1, 1, 2, 3, 4, 4, 5, 7, 7, 7, 10 };
    
    int previousnumber = -1;
    List<int> doubleDigits = new List<int>();
    for (int i = 0; i < intarray.Length; i++)
    {
        if (previousnumber == -1) { previousnumber = intarray[i]; continue; }
        if (intarray[i] == previousnumber)
        {
            if (!doubleDigits.Contains(intarray[i]))
            {
                doubleDigits.Add(intarray[i]);
                //Console.WriteLine("Duplicate int found - " + intarray[i]);
                continue;
            }
        }
        else
        {
            previousnumber = intarray[i];
        }
    }
    
    for (int i = 1; i < list.Count; i++)
        if (list[i] == list[i - 1])
            doubles.Add(list[i]);
    
    list.GroupBy(i => i).Where(g => g.Count() > 1).SelectMany(g => g.Skip(1))