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