Нахождение вхождения максимального значения в массиве - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь найти вхождения максимального значения в массиве целых чисел.

например,

int[] ar = [3, 1, 2, 3];

Здесь значение Max 3 повторяется дважды, поэтому ожидаемый результат равен2.

Это работает, я получаю счет как 2, поскольку максимальное значение 3 дважды встречается в массиве

var max = int.MinValue;
var occurrenceCount = 0;

foreach(var x in ar)
{
    if (x >= max) max = x;
}

foreach(var x in ar)
{
    if (x == max) occurrenceCount++;
}

Выход: 2 //occrenceCount

С Linq все проще,

var occurrenceCount = ar.Count(x => x == ar.Max())

Вывод: 2 // adventrenceCount

Теперь без Linq, Есть какой-нибудь упрощенный или эффективный способ сделать это?

Ответы [ 4 ]

0 голосов
/ 18 октября 2018

Вы можете попробовать более гибкий подход:

using System.Collections.Generic;

namespace ConsoleApp42
{
    class Program
    {
        static void Main (string[] args)
        {
            var array = new int[] { 1, 2, 3, 1, 1, 4, 4, 4, 4, 1, 1, 1 };
            //var array = new string[] { "a", "b", "a", "a" };

            var result = array.MaxCount ();
        }
    }

    public static class Extensions
    {
        public static (long count, T max) MaxCount<T> (this IEnumerable<T> source, IComparer<T> comparer = null)
        {
            if (comparer is null) comparer = Comparer<T>.Default;

            (long count, T max) result = (0, default (T));

            foreach (var element in source)
            {
                if (result.count == 0) // is first element?
                {
                    result.max = element;
                    result.count = 1;

                    continue;
                }

                int compareResult = comparer.Compare (element, result.max);

                if (compareResult == 0) // element == max
                {
                    result.count++;
                }
                else if (compareResult > 0) // element > max
                {
                    result.max = element;
                    result.count = 1;
                }
            }

            return result;
        }
    }
}
0 голосов
/ 18 октября 2018

Я не использовал linq.Я использовал lamda:)

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


        var result = ar.GroupBy(x => x) //values groups
        .Select(x => new
        {
            Number = x.Key,
            Count = x.Count()
        }).OrderByDescending(x => x.Count) //Short
        .FirstOrDefault(); //First Result


 result.Count // how many 

 result.Key   // max number

Нет Linq и нет Lamda

 int[] ar = new[] { 3, 1, 2, 3 };
            Array.Sort(ar);
            Array.Reverse(ar);
            var maxValue = ar[0];
            var occurrenceCount = 0;
            foreach (var item in ar)
            {
                if (item == maxValue)
                    occurrenceCount++;
            }
0 голосов
/ 18 октября 2018

На основе реализации Max и GetCount для Enumerable вы можете просто разложить на множители, добавив один тест в foreach типа Max:

public static int CountMax(this IEnumerable<int> source)
{
    if (source == null)
    {
        throw new ArgumentException();
    }

    int value = 0;
    bool hasValue = false;
    int count = 0;

    foreach (int x in source)
    {
        if (hasValue)
        {
            if (x > value)
            {
                value = x;
                count = 1;
            }
            else if (x == value)
            {
                count++;
            }
        }
        else
        {
            value = x;
            count = 1;
            hasValue = true;
        }
    }
    if (hasValue)
    {
        return count;
    }

    throw new Exception("no elements");
}

Самое интересное, что этолегко сделать его более общим, как:

public static int CountMax<TSource>(this IEnumerable<TSource> source) where TSource : IComparable
0 голосов
/ 18 октября 2018

По крайней мере, вы можете объединить два первых массива.Я бы все еще использовал решение Linq.Это понятнее.Если вы действительно хотите поговорить о производительности, сначала прочитайте Что быстрее? .

Итак, вот решение O (n):

int[] ar = {3, 1, 2, 3, 3, 4, 4};
int max = ar[0];
var occurrenceCount = 1;

for(var i = 1; i < ar.Length; i++)
{
    if (ar[i] > max) {
&#9;max = ar[i];
&#9;occurrenceCount = 1;
    }
    else if (ar[i] == max) {
        occurrenceCount++;
    }
}

WriteLine(max);
WriteLine(occurrenceCount);

Попробуйтеон-лайн!

  • Обратите внимание, что вы должны обработать случай, когда ваш массив пуст.
...