How to retrieve k random numbers from a vector of unknown size at compile time in C++

1 Answer

0 votes
#include <algorithm>
#include <iostream>
#include <random>
#include <stdexcept>
#include <vector>

/*
    Returns k randomly selected elements from the input vector.

    Characteristics:
    - Selects elements without replacement.
    - Each element can appear at most once in the result.
    - Works for vectors of any runtime size.
    - Uses std::sample (C++17), which is specifically designed
      for random sampling from a range.

    Complexity:
    - O(n), where n is the size of the input vector.

    Throws:
    - std::invalid_argument if k is larger than the vector size.
*/
std::vector<int> getRandomSample(
    const std::vector<int>& values,
    std::size_t k)
{
    if (k > values.size()) {
        throw std::invalid_argument(
            "Sample size cannot exceed vector size.");
    }

    // Random device used to seed the generator.
    std::random_device rd;

    // Mersenne Twister engine.
    std::mt19937 generator(rd());

    std::vector<int> result;
    result.reserve(k);

    std::sample(
        values.begin(),
        values.end(),
        std::back_inserter(result),
        k,
        generator);

    return result;
}

int main()
{
    try
    {
        // Example data.
        std::vector<int> numbers{
            10, 20, 30, 40, 50,
            60, 70, 80, 90, 100
        };

        std::size_t k = 4;

        std::vector<int> sample =
            getRandomSample(numbers, k);

        std::cout << "Random sample:\n";

        for (int value : sample) {
            std::cout << value << ' ';
        }

        std::cout << '\n';
    }
    catch (const std::exception& ex) {
        std::cerr << "Error: "
                  << ex.what()
                  << '\n';

        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}


/*
run:

Random sample:
40 60 80 90 

*/

 



answered Oct 1 by avibootz
...