【问题标题】:How can I count the number of times a value reoccurs within the same array?如何计算一个值在同一个数组中重复出现的次数?
【发布时间】:2014-09-22 22:44:27
【问题描述】:

正如标题所说,我试图计算一个值在同一个数组中重复出现的次数。因此,例如,如果有一个值为 1、1、2、2 的数组,则输出将类似于: 值 (1) 出现 (2) 次 \n 值 (2) 出现 (2) 次。到目前为止,这是我所拥有的:

foreach (var i in anArray)
{
    foreach (var m in secondArray)
    {
        if (i == m)
        {
            count++;
        }
    }
    Console.WriteLine("\nValue " + i + " occurred " + count + " times"); 
}

我创建了第一个数组 (secondArray) 的副本,并试图对数组进行适当的比较,但有些不对劲。嵌套循环计算我的值两次。因此,如果它会说:值 (1) 发生 (2) 次,下一个读数会说:值 (1) 发生 (4) 次,而不是移动到下一个不是 (1) 的值。我意识到它正在计算第二个(1)并将前一个计数添加到它......至少我想我意识到了。我怎样才能只使用数组而不使用列表来解决这个问题?

【问题讨论】:

  • O(n^2) 的复杂度有点不幸。
  • 你为什么要做第二个数组?
  • 数组中数字的本质是什么。它们可以任意大吗?他们往往很小 - 例如,低于某个小数字?数组中的数字可以是 -ve 吗?阵列可以有多大?可以使用额外的内存来获得答案吗?算法的性能是否值得关注?

标签: c# arrays nested-loops


【解决方案1】:

在您当前的设计中,您可以预先设置计数:

foreach (var i in anArray)
{
    count = 0; // Initialize each loop
    foreach (var m in secondArray)
    {
        if (i == m)
        {
            count++;
        }
    }
    Console.WriteLine("\nValue " + i + " occurred " + count + " times"); 
}

话虽如此,您可以从第二个数组构建一个字典,并使用它:

var dict = secondArray.GroupBy(v => v).ToDictionary(g => g.Key, g => g.Count());
foreach(var i in anArray)
{
    if (dict.ContainsKey[i])
        Console.WriteLine("\nValue " + i + " occurred " + dict[i] + " times"); 
    else
        Console.WriteLine("\nValue " + i + " occurred 0 times"); 
}

【讨论】:

  • 这看起来可行。我必须先恢复我的代码,然后才能对其进行测试。我仍然认为不仅仅是显示:“值 (1) 发生 (2) 次”一次,它会跳转到数组中的下一个 (1) 并再次显示该字符串……这适用于每个重复值。我怎样才能让它为每个重复值显示一次计数?
  • @BenignBaboon 如果anArray 有重复,就做foreach(var i in anArray.Distinct()) { ...
  • 非常感谢。它有效,现在我的工具箱中有一个新工具。
【解决方案2】:

你可以使用 linq

var counts = anArray.Concat(secondArray)
   .GroupBy(x => x)
   .Select(g => new { Number = g.Key, Count = g.Count() });

foreach(var c in counts)
{
     Console.WriteLine("\nValue " + c.Number + " occurred " + c.Count + " times"); 
}

【讨论】:

    【解决方案3】:

    使用 group by,您可以将其设置为单行来显示事件...

     anArray.GroupBy(a => a).ToList()
         .ForEach(g => Console.WriteLine("Value {0} occurs {1} times", g.Key, g.Count()));
    

    【讨论】:

      【解决方案4】:

      另一个版本:

      foreach (var distinctItem in anArray.Distinct())
      {
          Console.WriteLine("\nValue '{0}' occurred '{1}' times.", distinctItem,
              anArray.Count(i => i == distinctItem));
      }
      

      【讨论】:

        【解决方案5】:

        您可以将 system.linq 命名空间添加到您的类中,然后:

         var result = l.GroupBy(a => a).Select(s => new {Key= s.Key ,Counter= s.Count()});
          foreach (var item in result)
             Console.WriteLine("Value {0} occurred {1} times",item.Key,item.Counter);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-03
          • 2012-10-25
          • 1970-01-01
          • 1970-01-01
          • 2015-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多