【问题标题】:How can I count the unique numbers in an array without rearranging the array elements?如何在不重新排列数组元素的情况下计算数组中的唯一数字?
【发布时间】:2009-03-05 05:30:44
【问题描述】:

我无法计算数组中的唯一值,我需要这样做而不重新排列数组元素。

我怎样才能做到这一点?

【问题讨论】:

  • 家庭作业没有错...只要一个人不只是按原样接受答案。 (即,接受答案,并使其更好)。

标签: c# arrays algorithm


【解决方案1】:

如果你有 .NET 3.5,你可以通过 LINQ 轻松实现:

int numberOfElements = myArray.Distinct().Count();

非 LINQ:

List<int> uniqueValues = new List<int>();
for(int i = 0; i < myArray.Length; ++i)
{
    if(!uniqueValues.Contains(myArray[i]))
        uniqueValues.Add(myArray[i]);
}
int numberOfElements = uniqueValues.Count;

【讨论】:

  • 如果这是一个家庭作业问题,那么答案不太可能给他很多分,但在 linq 方面仍然是一个很好的答案。
  • 非 linq 的例子确实很糟糕,但是如果它确实是一个家庭作业问题,让我们让 Rich B 想出一个更好的解决方案。 :) (提示:如何避免为每个项目遍历整个数组?)
  • 让 Jarus 想出一个更好的解决方案,而不是。 (为什么不允许编辑 cmets!?)
  • 您可以删除cmets并重新编写。我就是这么做的。
  • 可以删除再重新添加。猜测编辑可能会掩盖对话的流程。
【解决方案2】:

这是一种效率更高的非 LINQ 实现。

        var array = new int[] { 1, 2, 3, 3, 3, 4 };
        // .Net 3.0 - use Dictionary<int, bool> 
        // .Net 1.1 - use Hashtable 
        var set = new HashSet<int>();
        foreach (var item in array) {
            if (!set.Contains(item)) set.Add(item);
        }
        Console.WriteLine("There are {0} distinct values. ", set.Count);

【讨论】:

  • 为什么是 而不是
  • 在性能方面它们应该是相同的,将清理它以使用 HashSet,因此这个演示代码看起来不那么难看
  • 字典包含在大数组上应该比列表包含的快得多。
  • 你不需要测试HashSet是否包含值。如果它包含, Add() 什么也不做。也许编译器知道要优化,但否则你会得到轻微的性能提升。
  • 事实证明,为已经存在的项目调用 .Add 比调用 .Contains ... 慢,所以这完全取决于您的输入数组
【解决方案3】:

O(n) 运行时间 max_value 内存使用量

boolean[] data = new boolean[maxValue];
for (int n : list) {
   if (data[n]) counter++
   else data[n] = true;
}

【讨论】:

    【解决方案4】:

    应该只计算不同的值还是应该计算数组中的每个数字(例如“数字 5 包含 3 次”)?

    第二个要求可以通过计数排序算法的起始步骤来满足。
    应该是这样的:

    • 建立一个索引/键所在的集合 要计算的元素
    • 一个键连接到一个保存出现次数的变量 关键要素
    • 迭代数组
      • key(array[index])的增量值

    问候

    【讨论】:

      猜你喜欢
      • 2020-12-11
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多