Наиболее частое число в массиве
У меня есть этот массив, я написал функцию MostFreq, которая принимает массив целых чисел и возвращает 2 значения: чем чаще число в массиве и его частота проверяют этот код, тем меньше, чем вы думаете? есть ли лучший способ сделать это?
static void Main()
{
int [] M={4,5,6,4,4,3,5,3};
int x;
int f=MyMath.MostFreq(M,out x );
console.WriteLine("the most Frequent Item = {0} with frequency = {1}",x,f);
}
=====
в классе Mymath
public static int MostFreq(int[] _M, out int x)
{
//First I need to sort the array in ascending order
int Max_Freq, No_Freq, i, k;
Array.Sort(_M);
k = _M[0];
Max_Freq = 0; i = 0; x = 0;
while (i < _M.Length)
{
//No_Freq= the frequency of the current number
No_Freq = 0;
//X here is the number which is appear in the array Frequently
while (k == _M[i])
{
No_Freq++;
i++;
if (i == _M.Length)
break;
}
if (No_Freq > Max_Freq)
{
//so it will be printed the same
Max_Freq = No_Freq;
x = k;
}
if (i < _M.Length) k = _M[i];
}
return (Max_Freq);
}
Ответы
Ответ 1
LINQ. Я знаю, что это в VB, но вы должны иметь возможность преобразовать его в С#:
Dim i = From Numbers In ints _
Group Numbers By Numbers Into Group _
Aggregate feq In Group Into Count() _
Select New With {.Number = Numbers, .Count = Count}
EDIT: теперь также на С#:
var i = from numbers in M
group numbers by numbers into grouped
select new { Number = grouped.Key, Freq = grouped.Count()};
Ответ 2
Предполагая, что вы не можете использовать LINQ, я бы, вероятно, подошел к алгоритму следующим образом:
- Создать словарь ключа/значения
- Итерируйте свой массив, добавьте ключ для словаря для каждого уникального элемента, увеличивайте значение каждый раз, когда этот элемент повторяется.
- Пройдите ключи словаря и верните элементу с самым высоким значением.
Это не отличное решение, но оно простое, ContainsKey - это поиск O (1), поэтому вы будете в большей степени повторять свой массив дважды.
Ответ 3
С точки зрения программного обеспечения я ожидал бы функцию MostFreq, чтобы вернуть элемент с самой высокой частотой - не самой частотой. Я бы переключил ваши и возвращаемые значения.
Ответ 4
Вы можете исключить сортировку, которую вы делаете в начале, итерации всего массива один раз, подсчет количества раз, когда вы сталкиваетесь с каждым значением во временном массиве, а затем итерации временного массива для максимального числа. Вы также можете хранить как самое высокое частоту, так и самый часто используемый элемент.
Различные типы имеют разную эффективность для разных типов данных, конечно, но это будет худший случай только двух итераций.
Изменить: Извинения за повтор... "Не знаю, когда я начал:)
Ответ 5
int count = 1;
int currentIndex = 0;
for (int i = 1; i < A.Length; i++)
{
if (A[i] == A[currentIndex])
count++;
else
count--;
if (count == 0)
{
currentIndex = i;
count = 1;
}
}
int mostFreq = A[currentIndex];
Ответ 6
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MostFrequentElement
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[] { 4, 1, 1, 4, 2, 3, 4, 4, 1, 2, 4, 9, 3, 1, 1, 7, 7, 7, 7, 7 };
Array.Sort(array, (a, b) => a.CompareTo(b));
int counter = 1;
int temp=0 ;
List<int> LOCE = new List<int>();
foreach (int i in array)
{
counter = 1;
foreach (int j in array)
{
if (array[j] == array[i])
{
counter++;
}
else {
counter=1;
}
if (counter == temp)
{
LOCE.Add(array[i]);
}
if (counter > temp)
{
LOCE.Clear();
LOCE.Add(array[i]);
temp = counter;
}
}
}
foreach (var element in LOCE)
{
Console.Write(element + ",");
}
Console.WriteLine();
Console.WriteLine("(" + temp + " times)");
Console.Read();
}
}
}
Ответ 7
Вот пример того, как вы могли бы сделать это без LINQ и без словарей и списков, всего два простых вложенных цикла:
public class MostFrequentNumber
{
public static void Main()
{
int[] numbers = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int counter = 0;
int longestOccurance = 0;
int mostFrequentNumber = 0;
for (int i = 0; i < numbers.Length; i++)
{
counter = 0;
for (int j = 0; j < numbers.Length; j++)
{
if (numbers[j] == numbers[i])
{
counter++;
}
}
if (counter > longestOccurance)
{
longestOccurance = counter;
mostFrequentNumber = numbers[i];
}
}
Console.WriteLine(mostFrequentNumber);
//Console.WriteLine($"occured {longestOccurance} times");
}
}
Вы получаете значение наиболее часто встречающегося числа, и (прокомментировал) вы могли бы получить также числа вхождений.
Я знаю, что у меня есть "использование Linq", это просто для преобразования исходной строки ввода в массив int и для сохранения пары строк и цикла синтаксического анализа. Алгоритм хорош даже без него, если вы заполните массив "длинным" способом...