【问题标题】:Find the most occurring number in a List<int>查找 List<int> 中出现次数最多的数字
【发布时间】:2023-03-06 05:51:01
【问题描述】:

有没有使用 linq 又快又好的方法?

【问题讨论】:

  • @AakashM,几乎可以肯定 lambda 表达式 OP 表示 linq,而不是一些委托/表达式方法。不知道为什么编辑被还原了。
  • @nawfal 1) 没有办法怀疑这个未注册用户 4 年前的意思,更不用说“几乎可以肯定”了。 2) find-occurrences 是一个可怜的标签,无论如何都是不合适的标签。 3)“linq”这个词不是代码,因此不应格式化为代码。在我看来,编辑的三个充其量有问题的部分为还原提供了完美的理由,但如果您不同意,请随时将其带到元数据。
  • @AakashM 我同意 3。不过,我编辑的要点是一个更明智的问题。您可以删除不适当的 (?) 标记以及代码格式,如果这对重新编辑而不是还原很重要的话。那么现在,无论如何都是不合适的标签,那么它更适合什么类型的问题呢? 2) 你认为 OP 的 lambda 表达式 是什么意思?我的观点是有一种怀疑的方式已经在 C# 圈子里呆了一段时间,鉴于 OP 选择的答案,这是一个强烈的怀疑。

标签: c# linq list


【解决方案1】:

怎么样:

var most = list.GroupBy(i=>i).OrderByDescending(grp=>grp.Count())
      .Select(grp=>grp.Key).First();

或在查询语法中:

var most = (from i in list
            group i by i into grp
            orderby grp.Count() descending
            select grp.Key).First();

当然,如果你会重复使用这个,你可以添加一个扩展方法:

public static T MostCommon<T>(this IEnumerable<T> list)
{
    return ... // previous code
}

那么你可以使用:

var most = list.MostCommon();

【讨论】:

  • 这就是我想要达到的目的,但我的大脑目前无法正常工作。
  • 如果答案不止一个元素怎么办?
  • 原生 LINQ 的最佳解决方案。尽管使用MoreLINQMaxBy(),您甚至可以执行以下操作:list.GroupBy(i=&gt;i).MaxBy(g=&gt;g.Count()).Key。除了更短更清晰之外,理论上它对于大型数据集(最大与排序)应该更有效。
  • 谢谢马克。它使我能够毫不费力地应用最常见的 kmers 问题。
【解决方案2】:

不确定 lambda 表达式,但我会

  1. 对列表进行排序 [O(n log n)]

  2. 扫描列表 [O(n)] 找到最长的运行长度。

  3. 再次扫描 [O(n)] 报告每个具有该游程长度的数字。

这是因为出现频率最高的数字可能不止一个。

【讨论】:

    【解决方案3】:

    有人要求解决存在关联的问题。这是一个尝试:

    int indicator = 0
    
    var result =
      list.GroupBy(i => i)
        .Select(g => new {i = g.Key, count = g.Count()}
        .OrderByDescending(x => x.count)
        .TakeWhile(x =>
        {
          if (x.count == indicator || indicator == 0)
          {
            indicator = x.count;
            return true;
          }
          return false;
        })
        .Select(x => x.i);
    

    【讨论】:

      【解决方案4】:

      摘自我的回答here

      public static IEnumerable<T> Mode<T>(this IEnumerable<T> input)
      {            
          var dict = input.ToLookup(x => x);
          if (dict.Count == 0)
              return Enumerable.Empty<T>();
          var maxCount = dict.Max(x => x.Count());
          return dict.Where(x => x.Count() == maxCount).Select(x => x.Key);
      }
      
      var modes = { }.Mode().ToArray(); //returns { }
      var modes = { 1, 2, 3 }.Mode().ToArray(); //returns { 1, 2, 3 }
      var modes = { 1, 1, 2, 3 }.Mode().ToArray(); //returns { 1 }
      var modes = { 1, 2, 3, 1, 2 }.Mode().ToArray(); //returns { 1, 2 }
      

      我在上述方法和David B'sTakeWhile之间进行了性能测试。

      来源 = { },迭代次数 = 1000000
      我的 - 300 毫秒,大卫的 - 930 毫秒

      来源 = { 1 },迭代次数 = 1000000
      我的 - 1070 毫秒,大卫的 - 1560 毫秒

      来源 = 100+ 个具有 2 个重复项的整数,迭代次数 = 10000
      我的 - 300 毫秒,大卫的 - 500 毫秒

      来源 = 10000 个随机整数,大约有 100 多个重复项,迭代次数 = 1000
      我的 - 1280 毫秒,大卫的 - 1400 毫秒

      【讨论】:

        【解决方案5】:

        这是另一个答案,似乎很快。我认为Nawfal's answer 通常更快,但这可能会在长序列上遮蔽它。

        public static IEnumerable<T> Mode<T>(
            this IEnumerable<T> source,
            IEqualityComparer<T> comparer = null)
        {
            var counts = source.GroupBy(t => t, comparer)
                .Select(g => new { g.Key, Count = g.Count() })
                .ToList();
        
            if (counts.Count == 0)
            {
                return Enumerable.Empty<T>();
            }
        
            var maxes = new List<int>(5);
            int maxCount = 1;
        
            for (var i = 0; i < counts.Count; i++)
            {
                if (counts[i].Count < maxCount)
                {
                    continue;
                }
        
                if (counts[i].Count > maxCount)
                {
                    maxes.Clear();
                    maxCount = counts[i].Count;
                }
        
                maxes.Add(i);
            }
        
            return maxes.Select(i => counts[i].Key);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-02-06
          • 2021-03-19
          • 1970-01-01
          • 2021-06-11
          • 2011-04-29
          • 1970-01-01
          相关资源
          最近更新 更多