Как найти режим в массиве С#?
Я хочу найти режим в массиве. Я знаю, что мне нужно делать вложенные циклы, чтобы проверять каждое значение и видеть, как часто появляется элемент в массиве. Затем я должен посчитать количество раз, когда появляется второй элемент. Код ниже не работает, может кто-нибудь мне помочь.
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];
}
}
Ответы
Ответ 1
Использование вложенных циклов - не лучший способ решить эту проблему. Он будет иметь время выполнения 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;
Вы также можете использовать расширение MaxBy
из метода MoreLINQ для дальнейшего улучшения решения, чтобы он требовал только повторения всех элементов один раз.
Ответ 2
Решение без 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);
Ответ 3
Как новичок, это может не иметь особого смысла, но стоит предложить решение на основе 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
Ответ 4
Скажем, массив 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