问题 数组中最常见的数字


我有这个数组我写了一个函数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);
}

11315
2017-11-10 22:10


起源

为什么这会被贬低并标记为冒犯? - FlySwat
@Brandon您使用的是哪个版本的C#? - Nathan W
我只是编辑了标签,以便人们知道要瞄准的版本。 - Nathan W
数据集中最常见的数字称为模式。所以也许这对命名你的方法很有用。 GetArrayMode()或类似的东西。 - mmcdole
@Nathan Thanx @Simucal是的我同意你的看法


答案:


LINQ它。我知道这是在VB中,但你应该能够将它转换为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}

编辑:现在也在C#中:

var i = from numbers in M
                group numbers by numbers into grouped
                select new { Number = grouped.Key, Freq = grouped.Count()};

7
2017-11-10 22:25



我喜欢你这样做:) - Maxime Rouiller


假设您不能使用LINQ,我可能会像这样处理算法:

  • 创建键/值字典
  • 迭代你的数组,为每个唯一元素添加一个字典,每次重复元素时增加值。
  • 走字典键,返回最高值的元素。

这不是一个很好的解决方案,但它很简单,ContainsKey是一个O(1)查找,所以你最多会迭代你的数组两次。


5
2017-11-10 22:32



是的,多数民众赞成很酷,我会尝试它


从软件工程的角度来看,我希望一个名为MostFreq的函数能够返回频率最高的元素 - 而不是频率本身。我会切换你的并返回值。


3
2017-11-10 22:26





您可以通过迭代整个数组一次来消除您在开始时所做的排序,保持计算临时数组中每个值的次数,然后迭代临时数组以获得最大数字。您也可以保持最高频率和最频繁的项目。

当然,不同种类对不同类型的数据具有不同的效率,但这只是两次迭代的最坏情况。

编辑:为重复道歉...'当我开始时,我不知道:)


1
2017-11-10 22:46





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];

0
2017-07-14 10:45



即使使用简单的算法,也可以通过这种方式解释它的作用和最重要的原因。有什么优点,缺点等:) - ForceMagic


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();
        }
    }
}

0
2018-03-04 03:54





这是一个如何在没有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数组并节省几行和一个解析循环。即使没有它,算法也很好,如果你用“长”方式填充数组......


0
2018-05-10 08:30





完成1次传球....

public class PopularNumber
    {
        private Int32[] numbers = {5, 4, 3, 32, 6, 6, 3, 3, 2, 2, 31, 1, 32, 4, 3, 4, 5, 6};

        public PopularNumber()
        {
            Dictionary<Int32,Int32> bucket = new Dictionary<Int32,Int32>();
            Int32 maxInt = Int32.MinValue;
            Int32 maxCount = 0;
            Int32 count;

            foreach (var i in numbers)
            {
                if (bucket.TryGetValue(i, out count))
                {
                    count++;
                    bucket[i] = count;
                }
                else
                {
                    count = 1;
                    bucket.Add(i,count);
                }

                if (count >= maxCount)
                {
                    maxInt = i;
                    maxCount = count;
                }

            }

            Console.WriteLine("{0},{1}",maxCount, maxInt);

        }
    }

0
2018-05-29 13:45