8 Key Standard Library Algorithms

Ensuring No Repeated Elements in std::ranges::sample()

Can I use std::ranges::sample() to ensure no repeated elements in the sample?

Abstract art representing computer programming

Yes, std::ranges::sample() ensures no repeated elements in the sample by its design.

The function samples without replacement, meaning once an element is selected, it cannot be selected again within the same sample operation.

Here is an example demonstrating this behavior:

#include <algorithm>
#include <iostream>
#include <vector>
#include <random>
#include <ranges>

int main() {
  std::vector<int> numbers{
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::vector<int> output;
  output.resize(5);

  auto rng = std::mt19937{std::random_device{}()};

  std::ranges::sample(
    numbers, output.begin(), output.size(), rng);

  std::ranges::for_each(output, [](int n) {
    std::cout << n << ", ";
  });
}
4, 9, 2, 7, 1,

In this example, std::ranges::sample() randomly selects 5 elements from the numbers vector without replacement. This ensures that each element in the output vector is unique.

If you need to perform sampling multiple times and want to ensure that the results are unique across multiple samples, you will need to adjust the source vector or handle it programmatically.

For example, to draw multiple unique samples from the same source vector:

#include <algorithm>
#include <iostream>
#include <random>
#include <ranges>
#include <vector>

int main() {
  std::vector<int> numbers{
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::vector<int> output1(5);
  std::vector<int> output2(5);

  auto rng = std::mt19937{std::random_device{}()};

  // First sample
  std::ranges::sample(
    numbers, output1.begin(), output1.size(), rng);

  std::ranges::for_each(output1, [](int n) {
    std::cout << n << ", ";
  });
  std::cout << "\n";

  // Remove sampled elements from the source
  for (int n : output1) {
    numbers.erase(
      std::remove(numbers.begin(), numbers.end(), n),
      numbers.end()
    );
  }

  // Second sample from the remaining elements
  std::ranges::sample(
    numbers, output2.begin(), output2.size(), rng);
  std::ranges::for_each(output2, [](int n) {
    std::cout << n << ", ";
  });
}
4, 9, 2, 7, 1,
8, 3, 10, 5, 6,

In this example, the first sample is taken, and then those elements are removed from the original numbers vector before taking the second sample. This ensures that no element is repeated across the two samples.

By using std::ranges::sample() and managing the source vector, you can ensure unique elements in your samples effectively.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved