10 методов генерации случайных уникальных чисел: изучение примеров кода

В различных задачах и приложениях программирования генерация случайных уникальных чисел является общим требованием. Независимо от того, создаете ли вы лотерейную систему, создаете уникальные идентификаторы или проводите статистическое моделирование, крайне важно иметь надежный метод генерации случайных и различных чисел. В этой статье мы рассмотрим десять различных методов достижения этой цели и приведем примеры кода для каждого подхода.

  1. Использование набора (Python):
    Встроенная структура данных Set в Python — это эффективный способ хранения уникальных элементов. Генерируя случайные числа в цикле while и добавляя их в набор до тех пор, пока не будет достигнуто желаемое количество, мы можем обеспечить уникальность.
import random
def generate_unique_numbers_set(count, lower_bound, upper_bound):
    unique_numbers = set()

    while len(unique_numbers) < count:
        unique_numbers.add(random.randint(lower_bound, upper_bound))

    return list(unique_numbers)
  1. Перетасовка массива (JavaScript):
    В JavaScript мы можем случайным образом перетасовать массив, используя алгоритм Фишера-Йейтса, а затем выбрать желаемое количество элементов из перетасованного массива.
function generateUniqueNumbersArray(count, lowerBound, upperBound) {
    const uniqueNumbers = [];

    for (let i = lowerBound; i <= upperBound; i++) {
        uniqueNumbers.push(i);
    }

    for (let i = uniqueNumbers.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [uniqueNumbers[i], uniqueNumbers[j]] = [uniqueNumbers[j], uniqueNumbers[i]];
    }

    return uniqueNumbers.slice(0, count);
}
  1. Использование HashSet (Java):
    Структура данных HashSet Java обеспечивает постоянную производительность основных операций, включая добавление элементов и проверку на дубликаты.
import java.util.HashSet;
import java.util.Random;
public class UniqueNumberGenerator {
    public static int[] generateUniqueNumbersHashSet(int count, int lowerBound, int upperBound) {
        HashSet<Integer> uniqueNumbers = new HashSet<>();
        Random random = new Random();

        while (uniqueNumbers.size() < count) {
            uniqueNumbers.add(lowerBound + random.nextInt(upperBound - lowerBound + 1));
        }

        int[] result = new int[count];
        int index = 0;

        for (int number : uniqueNumbers) {
            result[index++] = number;
        }

        return result;
    }
}

<ол старт="4">

  • Битовая манипуляция (C++):
    Используя побитовые операции, мы можем генерировать случайные уникальные числа в заданном диапазоне. Этот метод подходит, когда диапазон относительно небольшой.
  • #include <iostream>
    #include <vector>
    #include <random>
    std::vector<int> generateUniqueNumbersBitwise(int count, int lowerBound, int upperBound) {
        std::vector<int> uniqueNumbers;
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(lowerBound, upperBound);
        int bitmapSize = upperBound - lowerBound + 1;
        std::vector<bool> bitmap(bitmapSize, false);
    
        while (count > 0) {
            int randomNumber = dis(gen) - lowerBound;
    
            if (!bitmap[randomNumber]) {
                bitmap[randomNumber] = true;
                uniqueNumbers.push_back(randomNumber + lowerBound);
                count--;
            }
        }
    
        return uniqueNumbers;
    }
    1. Использование UUID (Python).
      UUID (универсальные уникальные идентификаторы) — это 128-битные числа, которые можно сгенерировать с помощью модуля uuidв Python. Хотя UUID и не являются случайными, они по сути уникальны и могут служить идентификаторами.
    import uuid
    def generate_unique_uuids(count):
        unique_uuids = []
    
        for _ in range(count):
            unique_uuids.append(str(uuid.uuid4()))
    
        return unique_uuids
    1. Выборка без замены (R).
      В R мы можем добиться генерации случайных уникальных чисел путем выборки без замены из заданного диапазона.
    generateUniqueNumbers <- function(count, lowerBound, upperBound) {
      uniqueNumbers <- sample(lowerBound:upperBound, count, replace = FALSE)
      return(uniqueNumbers)
    }
    1. Использование SecureRandom (Java):
      Класс SecureRandomв Java предоставляет криптографически стойкий генератор случайных чисел. Генерируя случайные числа в нужном диапазоне, мы можем обеспечить уникальность.
    import java.security.SecureRandom;
    import java.util.Arrays;
    public class UniqueNumberGenerator {
        public static int[] generateUniqueNumbersSecureRandom(int count, int lowerBound, int upperBound) {
            SecureRandom secureRandom = new SecureRandom();
            int[] uniqueNumbers = new int[count];
    
            for (int i = 0; i < count; i++) {
                uniqueNumbers[i] = lowerBound + secureRandom.nextInt(upperBound - lowerBound + 1);
            }
    
            return uniqueNumbers;
        }
    }
    1. Алгоритм Фишера-Йейтса (Python):
      Алгоритм Фишера-Йейтса также можно использовать в Python для перетасовки списка чисел и выбора нужного количества.
    import random
    def generate_unique_numbers_fisher_yates(count, lower_bound, upper_bound):
        numbers = list(range(lower_bound, upper_bound + 1))
        random.shuffle(numbers)
        return numbers[:count]
    1. Использование SecureRandom (C#):
      В C# пространство имен System.Security.Cryptographyпредоставляет класс RandomNumberGenerator, который может генерировать криптографически безопасные случайные числа.
    using System.Security.Cryptography;
    public class UniqueNumberGenerator
    {
        public static int[] GenerateUniqueNumbersSecureRandom(int count, int lowerBound, int upperBound)
        {
            using (var rng = new RNGCryptoServiceProvider())
            {
                var uniqueNumbers = new int[count];
                var byteArray = new byte[4];
    
                for (var i = 0; i < count; i++)
                {
                    rng.GetBytes(byteArray);
                    var randomValue = BitConverter.ToInt32(byteArray, 0);
                    var randomNum = lowerBound + (Math.Abs(randomValue) % (upperBound - lowerBound + 1));
                    uniqueNumbers[i] = randomNum;
                }
    
                return uniqueNumbers;
            }
        }
    }
    1. Использование класса Random (C#):
      Класс Randomв C# можно использовать для генерации случайных чисел в пределах диапазона. Отслеживая ранее сгенерированные номера, мы можем обеспечить уникальность.
    using System;
    using System.Collections.Generic;
    public class UniqueNumberGenerator
    {
        public static int[] GenerateUniqueNumbersRandomClass(int count, int lowerBound, int upperBound)
        {
            var random = new Random();
            var uniqueNumbers = new List<int>();
    
            while (uniqueNumbers.Count < count)
            {
                var randomNum = random.Next(lowerBound, upperBound + 1);
    
                if (!uniqueNumbers.Contains(randomNum))
                {
                    uniqueNumbers.Add(randomNum);
                }
            }
    
            return uniqueNumbers.ToArray();
        }
    }

    В этой статье мы рассмотрели десять различных методов генерации случайных уникальных чисел с использованием различных языков программирования. Предпочитаете ли вы использовать наборы, перетасовку массивов, манипуляции с битами или использовать специализированные классы, существует множество подходов для удовлетворения ваших потребностей. Выберите метод, который лучше всего соответствует вашим требованиям и предпочтениям языка программирования, и наслаждайтесь созданием случайных уникальных чисел без особых усилий.