Как проверить, есть ли в моем массиве повторяющиеся значения внутри?

Итак, вот мой массив.

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

Я хочу создать цикл поиска, чтобы проверить, повторяются ли какие-либо значения. Как это сделать?

Я бы предпочел не использовать какие-либо специальные встроенные методы, так как это небольшой массив.

Ответ 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 return 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;
    }
}

Ответ 2

Общий метод расширения:

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

Ответ 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

рассмотрите мою реализацию generic и efficient

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

Ответ 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 раза медленнее, чем выше,
но ~ 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

Мы должны инициализировать j из i в первом цикле и добавить один (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]);
        }
    }
}

Ответ 7

        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;