1

我正在开发让教师对论文进行评分的软件,我需要了解教师是否对连续 3 篇论文给出了相同的评分。基本上我有一个成绩列表:

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

我需要在此列表中识别 90 年代和 95 年代(它们每个都连续给出 3 次)。

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

4

4 回答 4

7

您可以通过i从 2 循环到list.Length并检查 if来轻松完成此操作list[i] == list[i - 1] && list[i - 1] == list[i - 2]

例如,它可以这样写:

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/UGwFwq

如果您不希望在连续有 4 个(或更多)等于时重复报告,防止这种情况发生的一个好方法是简单地将临时变量保留在前一个“连续 3 个”上,并在之前检查你追加到欺骗列表。

像这样的东西:

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

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

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

于 2013-11-11T20:49:56.040 回答
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());
于 2013-11-11T21:10:49.943 回答
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;
            }
        }
    }
}
于 2013-11-11T20:58:44.120 回答
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());               
    }
于 2013-11-11T21:29:44.950 回答