如何查找列表中项目的最大连续出现次数<>?

时间:2017-04-15 00:48:04

标签: c# list

我想在列表中找到字符串的最大连续出现次数。 让我们说我有List其中Drivers有Driver.Name,Driver.Nationality,Driver.Car 现在我们有一个种族列表,我将获胜者存储在列表中

我想看看法拉利连续获胜的时间是多少,或法国车手连续获胜。

Drivers.add{Alex, French, Ferrari}
Drivers.add{Peter, Russian, Ferrari}
Drivers.add{John, USA, Mercedes}
Drivers.add{May, USA, Toyota}
Drivers.add{Hannah, French, Mercedes}

List<Drivers> Winners
Alex,
Peter,
Alex,
John
May,
John,
Hannah

And the results:
Max Ferrari 3
Max USA 3

这是我尝试使用Color参数的方法。 &#34; R&#34;是一个赛车手的名单。它有效,我只是在寻找更优雅的方式。

foreach(var e in R)
{
     if (e.Color == lastColor)
     { Current++;
    if (Current > Max) { Max = Current; maxColor = e.Color; }
  }
     else { lastColor = e.Color; Current = 1; }
 } 

2 个答案:

答案 0 :(得分:0)

你应该能够在O(n)时间内完成这个操作,只需使用一个int变量作为'max run length',一个int变量作为字符串的'当前运行长度'。您可以遍历列表并跟踪当前和最大运行长度。

答案 1 :(得分:0)

没有简单的方法,因为.NET没有任何东西可以对连续项进行分组。

var Drivers = new[] { new { Name = "Alex"  , Team = "Ferrari"  },
                      new { Name = "Peter" , Team = "Ferrari"  },
                      new { Name = "John"  , Team = "Mercedes" },
                      new { Name = "May"   , Team = "Toyota"   },
                      new { Name = "Hannah", Team = "Mercedes" } };

var Winners = "Alex Peter Alex John May John Hannah".Split();

var Teams = Winners.Join(Drivers, w => w, d => d.Name, (w, d) => d.Team);   // Ferrari, Ferrari, Ferrari, Mercedes, Toyota, Mercedes, Mercedes

var Counts = Teams.Aggregate(new List<Tuple<int, string>>(), (L, t) => { L.Add(
    Tuple.Create(L.Any() && L.Last().Item2 == t ? L.Last().Item1 + 1 : 1, t)); return L; });   // (1, Ferrari), (2, Ferrari), (3, Ferrari), (1, Mercedes), (1, Toyota), (1, Mercedes), (2, Mercedes)

var Max = Counts.Max();    // (3, Ferrari)

MoreLinq等自定义扩展方法可用于缩短聚合部分:

var Max = Teams.GroupAdjacent(t => t).MaxBy(g => g.Count());

Debug.Print("Max " + Max.Key + " " + Max.Count()); // "Max Ferrari 3"