如何在数组C#中找到模式?

时间:2011-11-24 17:10:43

标签: c#

我想在数组中找到模式。我知道我必须做嵌套循环来检查每个值,看看数组中的元素出现的频率。然后我必须计算第二个元素出现的次数。以下代码不起作用,任何人都可以帮助我。

for (int i = 0; i < x.length; i ++)
{
    x[i]++;
    int high = 0;
    for (int i = 0; i < x.length; i++)
    {
        if (x[i] > high)
        high = x[i];
    }
}

4 个答案:

答案 0 :(得分:34)

使用嵌套循环不是解决此问题的好方法。它的运行时间为O(n ^ 2) - 比最佳O(n)差得多。

您可以通过对相同的值进行分组,然后找到具有最大计数的组来完成LINQ:

int mode = x.GroupBy(v => v)
            .OrderByDescending(g => g.Count())
            .First()
            .Key;

这既简单又快捷。但请注意(与LINQ to SQL不同)当只需要第一个结果时,LINQ to Objects当前不会优化OrderByDescending。它完整​​地对整个结果集进行排序,这是一个O(n log n)操作。

您可能需要此O(n)算法。它首先在组中迭代一次以找到最大计数,然后再次找到该计数的第一个相应键:

var groups = x.GroupBy(v => v);
int maxCount = groups.Max(g => g.Count());
int mode = groups.First(g => g.Count() == maxCount).Key;

您还可以使用MoreLINQ方法的MaxBy扩展来进一步改进解决方案,这样它只需要遍历所有元素一次。

答案 1 :(得分:8)

非LINQ解决方案:

int[] x = new int[] { 1, 2, 1, 2, 4, 3, 2 };

Dictionary<int, int> counts = new Dictionary<int, int>();
foreach( int a in x ) {
    if ( counts.ContainsKey(a) )
        counts[a] = counts[a]+1
    else
        counts[a] = 1
}

int result = int.MinValue;
int max = int.MinValue;
foreach (int key in counts.Keys) {
    if (counts[key] > max) {
        max = counts[key];
        result = key;
    }
}

Console.WriteLine("The mode is: " + result);

答案 2 :(得分:4)

作为初学者,这可能没有多大意义,但值得提供基于LINQ的解决方案。

x
.GroupBy(i => i) //place all identical values into groups
.OrderByDescending(g => g.Count()) //order groups by the size of the group desc
.Select(g => g.Key) //key of the group is representative of items in the group
.First() //first in the list is the most frequent (modal) value

答案 3 :(得分:1)

说,x数组包含以下项目:

int[] x = { 1, 2, 6, 2, 3, 8, 2, 2, 3, 4, 5, 6, 4, 4, 4, 5, 39, 4, 5 };

一个。获得最高价值:

int high = x.OrderByDescending(n => n).First();

湾获得模态:

int mode = x.GroupBy(i => i)  //Grouping same items
            .OrderByDescending(g => g.Count()) //now getting frequency of a value
            .Select(g => g.Key) //selecting key of the group
            .FirstOrDefault();   //Finally, taking the most frequent value