-1

C # code:

I have 20 random numbers between 1-100 in an array and the program should check if every value is unique. Now i should use another method which returns true if there are only unique values in the array and false if there are not any unique values in the array. I would appreciate if someone could help me with this.

3 Answers3

8
bool allUnique = array.Distinct().Count() == array.Count(); // or array.Length

or

var uniqueNumbers = new HashSet<int>(array);
bool allUnique = uniqueNumbers.Count == array.Count();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
5

A small alternative to @TimSchmelters excellent answers that can run a bit more efficient:

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

What this basically does is generating a for loop:

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;
}

From the moment one hs.Add fails - this because the element already exists - the method returns false, if no such object can be found, it returns true.

The reason that this can work faster is that it will stop the process from the moment a duplicate is found whereas the previously discussed approaches first construct a collection of unique numbers and then compare the size. Now if you iterate over large amount of numbers, constructing the entire distinct list can be computationally intensive.

Furthermore note that there are more clever ways than generate-and-test to generate random distinct numbers. For instance interleave the generate and test procedure. Once a project I had to correct generated Sudoku's this way. The result was that one had to wait entire days before it came up with a puzzle.

Community
  • 1
  • 1
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 2
    ++: i even prefer this over mine – Tim Schmelter Jan 26 '15 at 14:26
  • 1
    Tim's method could be slightly faster if `data` implments `ICollection`, the constructor that takes in a `IEnumerable` [has some optimizations](http://referencesource.microsoft.com/System.Core/R/d0822f25708256c5.html) to pre-size it's internal storage if the source enumerable implements `ICollection` – Scott Chamberlain Jan 26 '15 at 14:48
  • 1
    @ScottChamberlain: in case there are no duplicates, yes. In case there are duplicates (on average [87%](http://www.wolframalpha.com/input/?i=1-100!%2F%28%28100-n%29!*100^n%29+with+n%3D20) of the cases it will probably be a bit faster. The optimization lies in breaking of the processing immediately. But in case there are no duplicates, it can indeed result in a *O(log n)* overhead for reorganizing the `HashSet` now and then. – Willem Van Onsem Jan 26 '15 at 14:53
1

Here's a non linq solution

  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");
        }
    }   
  }
The One
  • 4,560
  • 5
  • 36
  • 52
  • 2
    This works but is less efficient since it scales quadratic in time whereas a `HashSet`-approach like `Distinct()` have an average time complexity of *O(n)* and (depending on the implementation of the `HashSet`) sometimes a guaranteed complexity of *O(n log n)* – Willem Van Onsem Jan 26 '15 at 14:34
  • 2
    Something tells me that this is for homework. @CommuSoft – The One Jan 26 '15 at 14:35
  • 1
    You could/should still use a hashset and save a ton of time, you could still make it "Non Linq" by replacing your inner `for` loop with `if(hs.Add(YourArray[i])` – Scott Chamberlain Jan 26 '15 at 14:44
  • @ScottChamberlain if you post that as an answer, I'll upvote it. – The One Jan 26 '15 at 14:47
  • No, I wont. That answer would just be expanding the LINQ in CommuSoft's answer to be a for loop without adding any value. – Scott Chamberlain Jan 26 '15 at 14:52