【问题标题】:Finding the most frequent number in an array using just a single pass仅使用一次遍历即可找到数组中出现频率最高的数字
【发布时间】:2018-09-29 14:35:41
【问题描述】:

所以我试图找出一个算法来搜索一个数组,只需一次通过即可找到其中出现的最频繁的数字。我尝试使用两个内部循环来解决它并且它可以工作,但这需要多次循环遍历数组。

现在,我正试图通过一次“扫描”数组来找到最常见的数字来找出另一种方法。有人有什么建议可以帮助吗?

【问题讨论】:

标签: c# arrays


【解决方案1】:

使用 LINQ,您可以简单地使用,

var mostfrequent = myList.GroupBy(i=>i).OrderByDescending(grp=>grp.Count())
      .Select(grp=>grp.Key).First();

DOTNET FIDDLE

编辑

根据OP对Hashtable的要求,可以如下实现,

            int mostCommom = array[0];
            int occurences = 0;
            foreach (int num in array)
            {
                if (!hs.ContainsKey(num))
                {
                    hs.Add(num, 1);
                }
                else
                {
                    int tempOccurences = (int)hs[num];
                    tempOccurences++;
                    hs.Remove(num);
                    hs.Add(num, tempOccurences);

                    if (occurences < tempOccurences)
                    {
                        occurences = tempOccurences;
                        mostCommom = num;
                    }
                }
            }
            foreach (DictionaryEntry entry in hs)
            {
                Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
            }
            Console.WriteLine("The commmon numer is " + mostCommom + " And it appears " + occurences + " times");

most frequent element in an Array

【讨论】:

  • 在 C# 或 Java 中怎么样?
  • @TomCold 它在 C# 中!
  • @TomCold 这是在 C# 中
  • 谁能解释发生了什么?
  • 我也在考虑使用哈希表,但这也违反了我想要的规则。
【解决方案2】:

您可以使用字典并将键设置为数字,然后当您遇到一个您已经遇到的数字时,将当前数字的值(即键)加 1,当数组完成时,用最高值。

【讨论】:

  • 这是否违反规则?
  • 还是使用hashtable更高效?
  • 不,你只需要遍历数组一次
  • 我认为 Sajeetharan 对第一个答案的评论实际上是我刚才所说的,但在代码版本中 ^^
  • 是的,但我想知道使用字典或哈希表的差异是什么
【解决方案3】:

这样的事情应该可以工作(您需要获取 ValueTuple NuGet 包才能使该元组调用签名工作):

 public static IEnumerable<int> ListOfInts = new List<int> { 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5 };

 public static (int? mostFrequent, int numOccurances) FindMostFrequent(IEnumerable<int> ints) {
     int maxNumOccurances = int.MinValue;
     int? mostFrequent = null;
     //key is number (that occurs), value is number of occurances
     var counters = new Dictionary<int, int>();
     foreach (var num in ints) {
         if (counters.TryGetValue(num, out var occurances)) {
             counters[num] = ++occurances;
         } else {
             counters[num] = 1;
         }
         if (occurances > maxNumOccurances) {
             mostFrequent = num;
             maxNumOccurances = occurances;
         }
     }
     return (mostFrequent, maxNumOccurances);
 }

它遍历整数集合一次。它在遍历列表时构建一个Dictionary&lt;int, int&gt;,执行 N 次查找和 N 次写入(插入或替换)。

如果列表为空,则返回的mostFrequent 部分将为null。如果最大值出现不止一次,您将得到第一个找到的。如果您想要最后一个,请将&gt; 更改为&gt;= in:

if (occurances > maxNumOccurances)

并且,如果您想要所有可能的结果,请在返回之前执行以下操作:

var maxes = from pair in counters where pair.Value == maxNumOccurances select pair;

【讨论】:

    猜你喜欢
    • 2017-07-18
    • 2011-09-09
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    相关资源
    最近更新 更多