【问题标题】:How do I check if my array has repeated values inside it?如何检查我的数组中是否有重复值?
【发布时间】:2013-11-14 11:56:07
【问题描述】:

这是我的数组。

double[] testArray = new double[10];
// will generate a random numbers from 1-20, too lazy to write the code

我想创建一个搜索循环来检查是否有重复的值。我该怎么做?

我不想使用任何特殊的内置方法,因为这是一个小数组。

【问题讨论】:

    标签: c# arrays repeat


    【解决方案1】:

    你可以用一点 Linq 做到这一点:

    if (testArray.Length != testArray.Distinct().Count())
    {
        Console.WriteLine("Contains duplicates");
    }
    

    Distinct 扩展方法删除所有重复项,Count 获取结果集的大小。如果它们完全不同,那么列表中有一些重复。

    或者,这里有更复杂的查询,但它可能更有效:

    if (testArray.GroupBy(x => x).Any(g => g.Count() > 1))
    {
        Console.WriteLine("Contains duplicates");
    }
    

    GroupBy 方法会将任何相同的元素组合在一起,如果任何组包含多个元素,Any 将返回 true

    上述两种解决方案都使用HashSet<T>,但您可以像这样直接使用一个:

    if (!testArray.All(new HashSet<double>().Add))
    {
        Console.WriteLine("Contains duplicates");
    }
    

    或者,如果您更喜欢完全不依赖 Linq 的解决方案:

    var hashSet = new HashSet<double>();
    foreach(var x in testArray) 
    {
        if (!hashSet.Add(x)) 
        {
            Console.WriteLine("Contains duplicates");
            break;
        }
    }
    

    【讨论】:

    • 哦,好的,谢谢。 Distinct().Count() 一般应该做什么?
    • 哦,我明白了。因此,如果我只想检查重复项,那么我只需删除 Distinct() 对吗?而 Count() 方法意味着它被复制了多少次作为结果集的大小?
    • @Mike no Count 将返回集合中的项目数,即testArray.Length == testArray.Count()。要获得重复的数量,您只需将两者相减即可,即testArray.Length - testArray.Distinct().Count()
    • 好的,谢谢第二个很好地检查是否有重复。
    【解决方案2】:

    看看我的实现它的genericefficient

    public static bool HasDuplicates<T>(IList<T> items)
        {
            Dictionary<T, bool> map = new Dictionary<T, bool>();
            for (int i = 0; i < items.Count; i++)
            {
                if (map.ContainsKey(items[i]))
                {
                    return true; // has duplicates
                }
                map.Add(items[i], true);
            }
            return false; // no duplicates
        }
    

    这里有一些电话

    string[] strings = new[] { "1", "2", "3" };
    Utility.HasDuplicates(strings)// this will return false
    
    int[] items=new []{1,2,3,1};
    Utility.HasDuplicates(items)// this will return true
    

    【讨论】:

    • 谢谢,我稍微修改了一下使用IEnumerable而不是IList。我也把它做成了扩展方法。
    【解决方案3】:

    使用这个:

    bool CheckUniqueness(double[] values)
    {
        var uniqueValues = new HashSet<double>();
        foreach (double d in values)
        {
            if(uniqueValues.Contains(d))
            {
                return false;
            }
            uniqueValues.Add(d);
        }
        return true;
    }
    

    【讨论】:

      【解决方案4】:

      我们必须在第一个循环中从 i 初始化 j 并添加一个(i+1),因为我们想将第一个循环值与同一个数组的下一个值进行比较。

      int[] arr = new int[]{1,2,3,1,4,2,5,4};
      
      //create one loop for arr values
      for (int i = 0;  i < arr.Length; i++)
      {
          //create nested loop for compare current values with actual value of arr
          for (int j = i+1; j < arr.Length; j++)
          {
      
              //and here we put our condition
              if (arr[i] == arr[j])
              {
                  Console.WriteLine(arr[i]);
              }
          }
      }
      

      【讨论】:

      • 此方法O(n^2)耗时太长,效率不高
      【解决方案5】:

      使用 (OP) 10 个随机双打相当快。 重复的机会:~0.000002 %。

      static bool repeat(double[] a)
      {
          return
              a[0] == a[1] || a[0] == a[2] || a[0] == a[3] || a[0] == a[4] ||
              a[0] == a[5] || a[0] == a[6] || a[0] == a[7] || a[0] == a[8] ||
              a[0] == a[9] || a[1] == a[2] || a[1] == a[3] || a[1] == a[4] ||
              a[1] == a[5] || a[1] == a[6] || a[1] == a[7] || a[1] == a[8] ||
              a[1] == a[9] || a[2] == a[3] || a[2] == a[4] || a[2] == a[5] ||
              a[2] == a[6] || a[2] == a[7] || a[2] == a[8] || a[2] == a[9] ||
              a[3] == a[4] || a[3] == a[5] || a[3] == a[6] || a[3] == a[7] ||
              a[3] == a[8] || a[3] == a[9] || a[4] == a[5] || a[4] == a[6] ||
              a[4] == a[7] || a[4] == a[8] || a[4] == a[9] || a[5] == a[6] ||
              a[5] == a[7] || a[5] == a[8] || a[5] == a[9] || a[6] == a[7] ||
              a[6] == a[8] || a[6] == a[9] || a[7] == a[8] || a[7] == a[9] ||
              a[8] == a[9];
      }
      

      更笼统,有 10 个数字,比上面慢 2 倍,
      但比 hashset 方法快约 7 倍。

      static bool repeat(double[] a)
      {
          int k = a.Length - 1;
          if (k < 70)
          {
              double aj;
              for (int i = 0, j; i < k; )
              {
                  for (aj = a[k--], j = k; j >= i; j--)
                      if (aj == a[j]) return true;
                  for (aj = a[i++], j = i; j <= k; j++)
                      if (aj == a[j]) return true;
              }
              return false;
          }
          var h = new HashSet<double>();
          while (k >= 0) if (!h.Add(a[k--])) return false;
          return true;
      }
      

      两行(缓慢重复;)

      static bool repeat(double[] a)
      { return (new HashSet<double>(a).Count < a.Length); }
      

      【讨论】:

        【解决方案6】:

        通用扩展方法:

        public static bool HasDuplicate<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer)
        {
            if (source == null)
                throw new ArgumentException(nameof(source));
        
            HashSet<T> set = new HashSet<T>(comparer);
            foreach (var item in source)
                if (!set.Add(item))
                    return true;
        
            return false;
        }
        

        【讨论】:

          【解决方案7】:

          使用哈希集添加成员,然后检查当前成员是否以前出现过

          public bool ContainsDuplicate(double[] nums) 
          {
                      int size = nums.Length;
                      HashSet<double> set1 = new HashSet<double>();
          
                      for (int i = 0; i < size; i++)
                      {
                          if (set1.Contains(nums[i]))
                          {
                              return true;
                          }
                          else
                          {
                              set1.Add(nums[i]);
                          }
                      }
                      return false;
          }
          

          【讨论】:

            【解决方案8】:
                    int[] nums = new int[] { 1, 2, 3, 4, 5};
            
            
            
                    Console.WriteLine(AnyDuplicate(nums));
                }
                /// <summary>
                /// Returns true if there is at least a duplicate in the array.
                /// </summary>
                /// <returns></returns>
                static bool AnyDuplicate(int[] numbers)
                {            
                    for (int i = 0; i < numbers.Length; i++)
                    {
                        for (int j = i + 1; j < numbers.Length; j++)
                        {
                            if (numbers[i] == numbers[j])
                            {
                                return true; 
                            }
                        }
                    }
                    return false;
            

            【讨论】:

              猜你喜欢
              • 2011-11-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-08-24
              相关资源
              最近更新 更多