【问题标题】:How do I find the mode (most frequent element) of an array? [duplicate]如何找到数组的模式(最常见的元素)? [复制]
【发布时间】:2013-11-13 08:06:12
【问题描述】:

这是我的数组:

int myArray = new int[5];

myArray[0] = 1;
myArray[1] = 1;
myArray[2] = 1;
myArray[3] = 3;
myArray[4] = 5;

如果我想让程序找到这个数组的模式,我需要写什么?

【问题讨论】:

  • 仅供参考,该语言被命名为“C#”,而不是“C Sharp”。
  • 这不是你的发音吗? @JohnSaunders。
  • 模式是数组中最常见的值@JeroenVannevel
  • 是的,但这不是你拼写的方式。
  • @JohnSaunders 好吧,我的错。

标签: c# .net arrays mode


【解决方案1】:

这是一个 LINQ 解决方案:

int mode = myArray
    .GroupBy(x => x)
    .OrderByDescending(g => g.Count())
    .First() // throws InvalidOperationException if myArray is empty
    .Key;

这会将myArray 的元素按值分组,按每组中值的数量对组进行排序,并取第一组的值。如果有多个模式,则采用myArray 中首先出现的模式(具有最低索引)。

如果可能有多个模式并且您需要所有模式,那么您可以改用此变体:

var groups = myArray
    .GroupBy(x => x)
    .Select(g => new { Value = g.Key, Count = g.Count() })
    .ToList(); // materialize the query to avoid evaluating it twice below
int maxCount = groups.Max(g => g.Count); // throws InvalidOperationException if myArray is empty
IEnumerable<int> modes = groups
    .Where(g => g.Count == maxCount)
    .Select(g => g.Value);

这会按值对myArray 的元素进行分组,查找任何组中的最大值数,并获取具有该最大值数的每个组的值。

如果myArray非常很大,那么第二个版本(O(n))可能比第一个版本(O(n log n))更快,因为排序原因)。

【讨论】:

  • +1。由于排序,最好使用 Max-by-count 来获得 O(n) 而不是 O(n log n) 进行整个操作 - 但 LINQ 中没有方便的在线方法来做到这一点(MoreLINQ 有 MaxBy )跨度>
  • @AlexeiLevenkov:好点。重复的问题有一个 O(n) 算法,它会扫描列表两次。
  • 代码有效,但是如果我不需要 InvalidOperationException 怎么办,因为我不需要检查数组是否为空?我应该删除什么?
  • @puretppc:如果数组为空,则技术上没有模式。在这种情况下,您希望mode 的值是多少?
猜你喜欢
  • 2011-04-05
  • 1970-01-01
  • 2019-10-16
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多