The intended goal of your code is sketchy at best, and your problem description isn't doing it any favors. The code itself could be taken a number of ways. I think you're trying to draw ten random numbers from a uniform distribution. The modern way to do that would be something like this:
Simple Uniform Distribution
#include <iostream>
#include <random>
int main()
{
std::mt19937 prng{ std::random_device{}() };
std::uniform_int_distribution<> dist(1, 10);
for (int i = 0; i < 10; ++i)
std::cout << dist(prng) << ' ';
std::cout.put('\n');
}
Note the seeding of the mersenne-twister prng, std::mt19937
, is done through the library interface to some source of entropy using std::random_device
. That prng is then used to feed the non-trivial mechanics of a std::uniform_int_distribution
, which is limited to the domain {1..10} inclusively. Note that this is not going to prevent duplicates. Some sample runs appear below (and it had better vary when you try it):
Output (varies)
7 8 3 4 4 5 8 5 5 3
Selection Without Replacement
If instead you're interested in drawing random selection without repetition there are a number of ways to do it, but the one I prefer for small domains like this is to simply sequence the numbers, random-shuffle them, then iterate to draw your random order. Again, we'll use a properly-seeded mersenne-twister prng, but this time we'll use it as the random source for a library-provided shuffle operation of a sequence we filled with our very-limited domain from which to draw:
#include <iostream>
#include <random>
#include <vector>
#include <numeric>
#include <algorithm>
int main()
{
std::mt19937 rng{ std::random_device{}() };
std::vector<int> vec(10);
std::iota(vec.begin(), vec.end(), 1);
std::shuffle(vec.begin(), vec.end(), rng);
for (auto x : vec)
std::cout << x << ' ';
std::cout.put('\n');
}
Output (varies)
6 7 10 2 4 8 3 1 5 9
Notable functions used above:
std::iota
is a simple ascending numeric sequence generation algorithm
std::shuffle
is a random shuffle algorithm utilizing a RNG source you provide to perform the shuffle operation.
Your Code
Both of the methods above are preferable to what you seem to be trying to do. Bias introduced with modulo against rand()
can be a real problem, and only you know for sure whether it will really matter. If you want to guard against it, use one of the methods I showed earlier (whichever is appropriate for your needs).
That said, your code is probably only missing a proper seeding. According to the library standard, any invoke of rand()
prior to seeing with srand
will behave as if srand(1)
was used. That explains your repetitious results from run to run. Assuming your use of v1
as both a control loop variable and a datum holder from rand
modulo calculation is a bug in its own, addressing both would look like this:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
std::srand(static_cast<unsigned>(std::time(nullptr)));
for (int i = 0; i < 10; ++i)
std::cout << 1 + std::rand() % 10 << ' ';
std::cout.put('\n');
}
Output (varies)
9 1 10 6 8 7 5 9 4 10
That said, I caution against doing this. There are plenty of things you can make mistakes on, and the bias is always in the background just waiting to bite. Use one of the other methods as warranted