【问题标题】:How to get the most common value in an Int array? (C#)如何获取 Int 数组中最常见的值? (C#)
【发布时间】:2011-02-08 23:46:19
【问题描述】:

如何使用 C# 获取 Int 数组中最常见的值

例如:数组具有以下值:1、1、1、2

Ans 应该是 1

【问题讨论】:

  • 整数值的域有限制吗? IE。所有的值都在 0 到 10 之间吗?
  • @Michael Petito:是的。如果范围不太大,可以很快完成。
  • 所有 int 都是正数且值不大于 5
  • 我认为有一个像 .Average() 或 .Max() 这样的函数
  • @mouthpiece,这些是可通过IEnumerable<T> 获得的扩展,但它们不适用于此处。平均值或最大值不会为您提供最常见的元素,而只是平均值或最大值。

标签: c# arrays int


【解决方案1】:
var query = (from item in array
        group item by item into g
        orderby g.Count() descending
        select new { Item = g.Key, Count = g.Count() }).First();

只考虑值而不是计数,你可以这样做

var query = (from item in array
                group item by item into g
                orderby g.Count() descending
                select g.Key).First();

第二个 Lambda 版本:

var query = array.GroupBy(item => item).OrderByDescending(g => g.Count()).Select(g => g.Key).First();

【讨论】:

  • 这不是在做O(nlogn)排序吗?
  • @liori:是的。排序并不是找到最高计数的最有效方法。
  • 我更喜欢 .First().Key 而不是自己使用 Select
【解决方案2】:

一些老式的高效循环:

var cnt = new Dictionary<int, int>();
foreach (int value in theArray) {
   if (cnt.ContainsKey(value)) {
      cnt[value]++;
   } else {
      cnt.Add(value, 1);
   }
}
int mostCommonValue = 0;
int highestCount = 0;
foreach (KeyValuePair<int, int> pair in cnt) {
   if (pair.Value > highestCount) {
      mostCommonValue = pair.Key;
      highestCount = pair.Value;
   }
}

现在mostCommonValue 包含最常见的值,highestCount 包含它出现的次数。

【讨论】:

  • +1 竭尽全力完成工作并没有错。
  • 第二部分可以通过使用MaxBy() 来简化。太糟糕了,它实际上不在 LINQ 中(但它在 MoreLinq 中)。
【解决方案3】:

我知道这篇文章很旧,但今天有人问我这个问题的反面。

LINQ 分组

sourceArray.GroupBy(value => value).OrderByDescending(group => group.Count()).First().First();

Temp Collection,类似于 Guffa 的:

var counts = new Dictionary<int, int>();
foreach (var i in sourceArray)
{
    if (!counts.ContainsKey(i)) { counts.Add(i, 0); }
    counts[i]++;
}
return counts.OrderByDescending(kv => kv.Value).First().Key;

【讨论】:

    【解决方案4】:
      public static int get_occure(int[] a)
        {
            int[] arr = a;
            int c = 1, maxcount = 1, maxvalue = 0;
            int result = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                maxvalue = arr[i];
                for (int j = 0; j <arr.Length; j++)
                {
    
                    if (maxvalue == arr[j] && j != i)
                    {
                        c++;
                        if (c > maxcount)
                        {
                            maxcount = c;
                            result = arr[i];
    
                        }
                    }
                    else
                    {
                        c=1;
    
                    }
    
                }
    
    
            }
            return result;
        }
    

    【讨论】:

      【解决方案5】:

      也许 O(n log n),但很快:

      sort the array a[n]
      
      // assuming n > 0
      int iBest = -1;  // index of first number in most popular subset
      int nBest = -1;  // popularity of most popular number
      // for each subset of numbers
      for(int i = 0; i < n; ){
        int ii = i; // ii = index of first number in subset
        int nn = 0; // nn = count of numbers in subset
        // for each number in subset, count it
        for (; i < n && a[i]==a[ii]; i++, nn++ ){}
        // if the subset has more numbers than the best so far
        // remember it as the new best
        if (nBest < nn){nBest = nn; iBest = ii;}
      }
      
      // print the most popular value and how popular it is
      print a[iBest], nBest
      

      【讨论】:

      • 你一开始没有说对数组进行排序:)。无论如何,如果您要进行排序,您可以更简单地执行此操作。一个 for 循环和几个变量就足够了。
      • @IVlad:那不是第一行代码吗?无论如何,你是对的。
      【解决方案6】:

      使用 linq 的另一种解决方案:

      static int[] GetMostCommonIntegers(int[] nums)
      {
          return nums
                  .ToLookup(n => n)
                  .ToLookup(l => l.Count(), l => l.Key)
                  .OrderBy(l => l.Key)
                  .Last() 
                  .ToArray();
      }   
      

      这个解决方案可以处理多个数字出现次数相同的情况:

      [1,4,5,7,1] => [1]
      [1,1,2,2,3,4,5] => [1,2]
      [6,6,6,2,2,1] => [6]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-04
        • 2015-08-18
        • 1970-01-01
        • 2020-07-09
        相关资源
        最近更新 更多