Подтвердить что ты не робот

Как найти режим в массиве С#?

Я хочу найти режим в массиве. Я знаю, что мне нужно делать вложенные циклы, чтобы проверять каждое значение и видеть, как часто появляется элемент в массиве. Затем я должен посчитать количество раз, когда появляется второй элемент. Код ниже не работает, может кто-нибудь мне помочь.

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];
    }
}
4b9b3361

Ответ 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