【问题标题】:Finding mode in List of integers [duplicate]在整数列表中查找模式[重复]
【发布时间】:2015-08-31 17:38:52
【问题描述】:

如何找到数字列表的模式?我知道它的逻辑(我认为),但我不知道如何实现该逻辑或将我的大脑的想法转换为可行的代码。

这是我所知道的:

我需要有一个循环遍历列表一次,以查看一个数字重复了多少次,以及一个数组来保存一个数字的重复次数。我还需要告诉我的程序在找到较大的数量后丢弃较小的数量。

【问题讨论】:

  • 这是家庭作业吗?如果是这样,您可以使用哪些库方法是否有限制?

标签: c# arrays list sorting mode


【解决方案1】:

一种 linq 方法,更简洁,但几乎可以肯定比 Yeldar Kurmangaliyev 的效率低:

int FindMode(IEnumerable<int> data)
{
    return data
        .GroupBy(n => n)
        .Select(x => new { x.Key, Count = x.Count() })
        .OrderByDescending(a => a.Count)
        .First()
        .Key;
}

这不处理data为空的情况,也不处理数据集中有两个或多个相同频率的数据点的情况。

【讨论】:

    【解决方案2】:

    是的,你是对的:

    让我们有一个列表数字

    List<int> myValues = new List<int>(new int[] { 1, 3, 3, 3, 7, 7 } );
    

    你需要有一个循环遍历列表一次

    foreach (var val in myValues)
    {
    }
    

    查看一个数字在数组中重复了多少次,以保存一个数字重复的次数

    Dictionary<int, int> repetitions = new Dictionary<int, int>(); 
    foreach (var val in myValues)
    {
        if (repetitions.ContainsKey(val))
            repetitions[val]++; // Met it one more time
        else
            repetitions.Add(val, 1); // Met it once, because it is not in dict. 
    }
    

    现在,您的字典 repetitions 存储了 key 值重复的次数(确切地说是 value)。
    然后,你需要找到模式的记录(即重复次数最多的记录(即最高值))并取这个。 LINQ 将帮助我们 - 让我们按值对数组进行排序并取最后一个……或者按降序排序并取第一个。实际上,就结果和生产力而言,这是相同的。

    var modeRecord = repetitions.OrderByDescending(x => x.Value).First();
    // or
    var modeRecord = repetitions.OrderBy(x => x.Value).Last();
    

    来了!这里我们有一个模式:

    List<int> myValues = new List<int>(new int[] { 1, 3, 3, 3, 7, 7 } );
    Dictionary<int, int> repetitions = new Dictionary<int, int>(); 
    
    foreach (var val in myValues)
    {
        if (repetitions.ContainsKey(val))
            repetitions[val]++; // Met it one more time
        else
            repetitions.Add(val, 1); // Met it once, because it is not in dict. 
    }
    
    var modeRecord = repetitions.OrderByDescending(x => x.Value).First();
    
    Console.WriteLine("Mode is {0}. It meets {1} times in an list", modeRecord.Key, modeRecord.Value);
    

    您的模式计算逻辑很好。您所需要的只是在代码中按照自己的说明进行操作:)

    【讨论】:

    • 好答案。更详细,但更高效(更少的键查找):int count; if (repetitions.TryGetValue(val, out count)) repetitions[val] = count + 1; else repetitions[val] = 1;
    【解决方案3】:

    这是另一种 LINQ 方法:

    var values = new int[] { 1, 3, 3, 3, 7, 7 };
    
    var mode =
        values
            .Aggregate(
                new { best = 0, best_length = 0, current = 0, current_length = 0 },
                (a, n) =>
                {
                    var current_length = 1 + (a.current == n ? a.current_length : 0);
                    var is_longer = current_length > a.best_length;
                    return new
                    {
                        best = is_longer ? n : a.best,
                        best_length = is_longer ? current_length : a.best_length,
                        current = n,
                        current_length,
                    };
                }).best;
    

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 2016-11-18
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      相关资源
      最近更新 更多