【问题标题】:How to check if random values are unique?如何检查随机值是否唯一?
【发布时间】:2015-01-26 14:16:01
【问题描述】:

C#代码:

我在一个数组中有 20 个 1-100 之间的随机数,程序应该检查每个值是否都是唯一的。现在我应该使用另一种方法,如果数组中只有唯一值,则返回 true,如果数组中没有任何唯一值,则返回 false。如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 提示:看Distinct()
  • 计算数组的元素,然后计算数组的不同元素并比较两个值。你可以用 Linq 做到这一点。
  • @GrantWinney:这不相关。使用 Linq,它将使用可以被覆盖的 Equals 方法。
  • 自己做功课,不然什么都学不到!
  • @GrantWinney:你当然可以。一个数组T[]继承自IEnumerable<T>...你只需要写using System.Linq

标签: c# arrays random numbers


【解决方案1】:
bool allUnique = array.Distinct().Count() == array.Count(); // or array.Length

var uniqueNumbers = new HashSet<int>(array);
bool allUnique = uniqueNumbers.Count == array.Count();

【讨论】:

    【解决方案2】:

    @TimSchmelters 的一个小替代方案,可以运行更高效的优秀答案:

    public static bool AllUniq<T> (this IEnumerable<T> data) {
        HashSet<T> hs = new HashSet<T>();
        return data.All(hs.Add);
    }
    

    这基本上是生成一个for 循环:

    public static bool AllUniq<T> (this IEnumerable<T> data) {
        HashSet<T> hs = new HashSet<T>();
        foreach(T x in data) {
            if(!hs.Add(x)) {
                return false;
            }
        }
        return true;
    }
    

    hs.Add失败的那一刻起-这是因为该元素已经存在-该方法返回false,如果找不到这样的对象,则返回true

    这可以更快地工作的原因是它会从发现重复的那一刻起停止该过程,而之前讨论的方法首先构造一个唯一数字的集合,然后比较大小。现在,如果您对大量数字进行迭代,则构建整个不同列表的计算量可能会很大。

    另外请注意,除了 generate-and-testgenerate random distinct numbers,还有更聪明的方法。例如交错 generatetest 过程。一旦一个项目我不得不以这种方式纠正生成的数独。结果是人们不得不等待一整天才想出一个谜题。

    【讨论】:

    • ++:我什至更喜欢这个而不是我的
    • 如果 data 实现 ICollection&lt;T&gt;,Tim 的方法可能会稍微快一点,如果源可枚举实现 ICollection&lt;T&gt;,构造函数接受 IEnumerable has some optimizations 来预先调整其内部存储的大小
    • @ScottChamberlain:如果没有重复,是的。如果有重复(平均87%的情况,它可能会快一点。优化在于立即中断处理。但如果没有重复,它确实会导致 O (log n) 不时重组HashSet&lt;T&gt; 的开销。
    【解决方案3】:

    这是一个非 linq 解决方案

      for(int i=0; i< YourArray.Length;i++)
      {
        for(int x=i+1;  x< YourArray.Length; x++)
        {
          if(YourArray[i] == YourArray[x])
            {
                Console.WriteLine("Found repeated value");
            }
        }   
      }
    

    【讨论】:

    • 这行得通,但效率较低,因为它在时间上是二次方的,而像 Distinct() 这样的 HashSet 方法的平均时间复杂度为 O(n) 和 (取决于HashSet) 的实现,有时会保证O(n log n)的复杂度
    • 某事告诉我这是做作业的。 @CommuSoft
    • 您可以/应该仍然使用哈希集并节省大量时间,您仍然可以通过将内部 for 循环替换为 if(hs.Add(YourArray[i]) 来使其成为“非 Linq”
    • @ScottChamberlain 如果您将其作为答案发布,我会投赞成票。
    • 不,我不会。这个答案只是将 CommuSoft 答案中的 LINQ 扩展为一个 for 循环,而不增加任何价值。
    猜你喜欢
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多