c# - test - El número más frecuente en una matriz
test online c# (7)
Tengo esta matriz. Escribí una función MostFreq que toma una matriz de enteros y devuelve 2 valores: el número más frecuente en la matriz y su frecuencia comprueban este código. ¿Qué crees? ¿Hay una mejor manera de hacerlo?
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);
}
=====
en la clase 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);
}
Asumiendo que no puedes usar LINQ, probablemente abordaría el algoritmo de esta manera:
- Crear diccionario clave / valor
- Itere su matriz, agregue una clave al diccionario para cada elemento único, incremente el valor cada vez que se repita ese elemento.
- Camine por las teclas del diccionario y devuelva el elemento con el valor más alto.
Esta no es una gran solución, pero es simple, ContainsKey es una búsqueda O (1), por lo que, como máximo, se repetirá dos veces.
Desde el punto de vista de la ingeniería de software, esperaría que una función llamada MostFreq devuelva el elemento con la frecuencia más alta, no la frecuencia en sí misma. Cambiaría tus valores de ida y vuelta.
LINQ arriba. Sé que esto está en VB pero deberías poder convertirlo a C #:
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}
EDITAR: ahora también en C #:
var i = from numbers in M
group numbers by numbers into grouped
select new { Number = grouped.Key, Freq = grouped.Count()};
Puede eliminar la clasificación que hace al comienzo iterando toda la matriz una vez, manteniendo un recuento de cuántas veces se encuentra con cada valor en una matriz temporal, y luego iterando la matriz temporal para el número más alto. También puede mantener el conteo de frecuencia más alto y el ítem más frecuente en todo momento.
Diferentes géneros tienen diferentes eficiencias en diferentes tipos de datos, por supuesto, pero este sería el peor caso de solo dos iteraciones.
Editar: disculpas por la repetición ... ''Tweren''t allí cuando comencé :)
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];
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();
}
}
}
Aquí hay un ejemplo de cómo podría hacerlo sin LINQ y sin diccionarios y listas, solo dos bucles anidados simples:
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");
}
}
Obtiene el valor del número que ocurre con mayor frecuencia, y (comentado) también puede obtener los números de las ocurrencias. Sé que tengo un "uso de Linq"; eso es solo para convertir la cadena de entrada inicial a una matriz int y para ahorrar un par de líneas y un ciclo de análisis. El algoritmo está bien incluso sin él, si llena la matriz de la forma "larga" ...