查找类似(或列表中的相同连续项)

时间:2013-11-11 20:47:51

标签: c# list

我正在研究让教师评分论文的软件,我需要找出教师是否已经连续3篇论文给出相同的成绩。基本上我有一个成绩列表:

80,81,90,90,90,100,85,86,86,79,95,95,95

我需要在此列表中识别90和95(它们各自连续3次)。

PS - 对于那些一直将我的帖子标记为“家庭作业”的人来说,仅仅因为我正在处理学生和成绩并不意味着这是一个课堂作业。吉米尼。

4 个答案:

答案 0 :(得分:7)

通过从{2}到i的{​​{1}}循环,您可以轻松完成此操作并检查是否list.Length

例如,它可以这样写:

list[i] == list[i - 1] && list[i - 1] == list[i - 2]

<强> [编辑]
这是一个正在运行的示例:http://ideone.com/UGwFwq

如果你不想在连续4个(或更多)等于时报告双重,那么防止这种情况发生的一个好方法就是找到前一个“连续3个”的临时变量并找到并检查在你附加到欺骗列表之前反对。

这样的事情:

var list = new[] { 80,81,90,90,90,100,85,86,86,79,95,95,95 };
var dupes = new List<int>();
for(var i = 2; i < list.Length; i++) {
    if(list[i] == list[i - 1] && list[i] == list[i - 2])
        dupes.Add(list[i]);
}

展示:http://ideone.com/jbokMQ

[编辑2]
如果由于某种原因你需要以类似LINQ的方式运行它(例如,如果你有一个巨大的数据集或数据流,并且你想以懒惰的方式运行它),解决方法可以在这里找到:http://ideone.com/R1ZBVk

答案 1 :(得分:2)

这是一个通用方法,用于对选定值相等的连续项进行分组:

public static IEnumerable<IEnumerable<TSource>> GroupConsecutive<TSource, TKey>(
    this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            yield break;

        TKey lastKey = selector(iterator.Current);
        List<TSource> list = new List<TSource>() { iterator.Current };
        IEqualityComparer<TKey> comparer = EqualityComparer<TKey>.Default;

        while (iterator.MoveNext())
        {
            TKey nextKey = selector(iterator.Current);
            if (comparer.Equals(lastKey, nextKey))
            {
                list.Add(iterator.Current);
            }
            else
            {
                yield return list;
                lastKey = nextKey;
                list = new List<TSource>() { iterator.Current };
            }
        }

        yield return list;
    }
}

我们现在可以在您的数据上使用它,如下所示:

var duplicates = data.GroupConsecutive(n => n)
    .Where(group => group.Count() >= 3);
    .Select(group => group.First());

答案 2 :(得分:0)

快速而肮脏:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3 {
    class Program {
        static void Main(string[] args) {
            List<byte> A = new List<byte>{80,81,90,90,90,100,85,86,86,79,95,95,95};
            byte last = 0;
            int count = 0;
            foreach (byte b in A) {

                if (b == last) count++;
                else count = 0;
                if (count >=2) Console.WriteLine("Instructor has given " + b + " " +     (count+1) + " times in a row");
                last = b;
            }
        }
    }
}

答案 3 :(得分:0)

你可以试试这个:

int intDuplicateCriteria = 2; //Any grade duplicated by a value greater than 2 
int[] lstGrades = new[] { 80, 81, 90, 90, 90, 100, 85, 86, 86, 79, 95, 95, 95 };

var lstDuplicate = lstGrades
                 .GroupBy(grade => grade)
                 .Where(g => g.Count() > intDuplicateCriteria)
                 .Select(g => g.Key);


//Display consecutively grades given 3 times
foreach (var d in lstDuplicate)
    {
      Console.WriteLine(d.ToString());               
    }