Fill a vector with random numbers c++
Asked Answered
E

8

42

I've got a vector that I'm trying to fill up with random numbers. I keep running into an issue however that the vector mostly outputs 0 each time that I'm running it (it shouldn't output a 0 ever). What am I doing wrong in my code written below to make it output 0 (it outputs 0 more so than any other number):

vector<int> myVector;
srand((unsigned)time(NULL));
int a = rand() % 20 + 1; //1 to 20    
for (int i =0; i < a; i++){
        int b = rand() % 20 + 1;
        myVector.push_back(b);
        cout << myVector[b] << endl;
    }

I am a beginner and have not done much C++ programming in a long time so I'm not sure what is making my code malfunction. If someone could explain what I've done wrong it would be greatly appreciated.

Ecthyma answered 2/2, 2014 at 21:38 Comment(2)
myVector[b] should be myVector[i]Edger
Or, arguably, it should be myVector.back()Phillips
S
8

You are calling the wrong index in your vector

Try doing:

cout << myVector[i] << endl;

else you will risk running off the end of your vertex for the first 20 or so iterations.

You can also call .back() on your vector to get the last item in the vector.

Seismic answered 2/2, 2014 at 21:41 Comment(4)
Ah, I figured it would be something small that I didn't see. In terms of speed would there be any difference between using .back() or [i]?Ecthyma
You would have to benchmark it but I strongly suspect .back() is faster and safer.Seismic
@Ecthyma btw, in the future if you have a C++11 implementation at your disposal I strongly suggest using the <random> library. It really solves a lot of issues such as modulo-bias. See it liveTauromachy
@Valrok: If you turn on optimalizations, they'll probably be equally fast. The optimizer should be able to generate functionally identical code.Faretheewell
Z
96

You can use the std::generate algorithm to fill a vector of n elements with random numbers.

In modern C++ it’s recommended not to use any time-based seeds and std::rand, but instead to use random_device to generate a seed. For software-based engine, you always need to specify the engine and distribution. Read More...

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

int main()
{
    // First create an instance of an engine.
    std::random_device rnd_device;
    // Specify the engine and distribution.
    std::mt19937 mersenne_engine {rnd_device()};  // Generates random integers
    std::uniform_int_distribution<int> dist {1, 52};
    
    auto gen = [&](){
                   return dist(mersenne_engine);
               };

    std::vector<int> vec(10);
    std::generate(vec.begin(), vec.end(), gen);
    
    // Optional
    for (const auto& i : vec) {
        std::cout << i << " ";
    }
}

If you want to rearrange the elements of a range in a random order:

std::shuffle(vec.begin(), vec.end(), mersenne_engine);
Zachariahzacharias answered 17/4, 2014 at 21:26 Comment(2)
You should bind a reference to the mersenne_engine using std::ref, otherwise generating multiple vectors with the same generator will cause all vectors to be the same. See the associated question.Escapement
Another note of warning, random_device may not be very random at all! GCC under Windows for example always produces the same output for your posted code.Escapement
E
48

What about simply:

#include <vector>
#include <algorithm>
#include <ctime>

std::srand(unsigned(std::time(nullptr)));
std::vector<int> v(1000);
std::generate(v.begin(), v.end(), std::rand);
Emulsify answered 22/4, 2018 at 0:25 Comment(2)
looks like it will fill it with the same valuesOvation
@x4444: On my machine it works after several tests. Maybe put a "std::srand(unsigned(std::time(nullptr)));" in front.Emulsify
T
14

Just adding my 2 cents... This response is similar to the one given by Marko Tunjic, but it doesn't use std::rand from C, but C++11 features instead. It allows you to use the distribution of your choice, uniform_int_distribution in the example below.

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

static std::vector<int> generate_data(size_t size)
{
    using value_type = int;
    // We use static in order to instantiate the random engine
    // and the distribution once only.
    // It may provoke some thread-safety issues.
    static std::uniform_int_distribution<value_type> distribution(
        std::numeric_limits<value_type>::min(),
        std::numeric_limits<value_type>::max());
    static std::default_random_engine generator;

    std::vector<value_type> data(size);
    std::generate(data.begin(), data.end(), []() { return distribution(generator); });
    return data;
}

int main()
{
    for (auto i = 0u; i < 5; ++i)
    {
        std::vector<int> myVector = generate_data(10);
        myVector = generate_data(10);

        std::cout << "myVector (iteration " << i << "): ";
        for (auto v: myVector)
        {
            std::cout << v << ",";
        }
        std::cout << "\n";
    }
}
Triptolemus answered 1/10, 2015 at 12:27 Comment(2)
You say Marko Tunjic's answer uses std::rand in C? Could you please explain that in more detail for me?Desperation
It used to use rand when I wrote my answer. Have a look at the first revision stackoverflow.com/revisions/23143753/1.Triptolemus
S
8

You are calling the wrong index in your vector

Try doing:

cout << myVector[i] << endl;

else you will risk running off the end of your vertex for the first 20 or so iterations.

You can also call .back() on your vector to get the last item in the vector.

Seismic answered 2/2, 2014 at 21:41 Comment(4)
Ah, I figured it would be something small that I didn't see. In terms of speed would there be any difference between using .back() or [i]?Ecthyma
You would have to benchmark it but I strongly suspect .back() is faster and safer.Seismic
@Ecthyma btw, in the future if you have a C++11 implementation at your disposal I strongly suggest using the <random> library. It really solves a lot of issues such as modulo-bias. See it liveTauromachy
@Valrok: If you turn on optimalizations, they'll probably be equally fast. The optimizer should be able to generate functionally identical code.Faretheewell
P
1

You are calling the wrong index in your vector

cout << myVector[i] << endl;
Pennyworth answered 2/2, 2014 at 21:44 Comment(0)
P
1

Its not clear what you are trying to do with the loop, the code is creating a vector of random size, filled with random numbers.

You are outputting "myVector[b]", but 'b' is the random value, not the index of just added number. You could just :

cout << b << endl;

But really you should size the vector, and just access by index.

int vec_size = rand() % 20 + 1;
vec<int> myvec(vec_size);
for( int i = 0; i < vec_size; ++i ) {
    vec[i] = rand() % 20 + 1;
}

/* output the list after you made it */
std::copy(myvec.begin(), myvec.end(),
        std::ostream_iterator<int>(cout, "\n"));
Philips answered 2/2, 2014 at 21:53 Comment(1)
The variable above it (a) is intentionally being a random number between 1 and 20, and I'm trying to make the vector be of size a with each index having a random number that is <= aEcthyma
A
-1
cout << myVector[b] ?!

it should be : cout << myVector[i];

Appreciation answered 2/2, 2014 at 22:3 Comment(0)
T
-2
// here I generate a vector that contains random vectors
// for example, after this code, vec = { {1,4,8}, {1,3,6,7,9}, {2,5,6} }

#include <vector>
#include <time.h>

void generate_random_vectors(const int num_of_rand_vectors, vector<vector<int>> &vec) {
    for (int j = 0; j < num_of_rand_vectors; ++j) {
        // the vector size will be randomal: between 0 to 19
        int vec_size = (rand() % 20);
        vector<int> rand_vec(vec_size);
        for (int k = 0; k < vec_size; ++k) {
            // each vec element will be randomal: between 1 to 20
            rand_vec[k] = 1 + (rand() % 20);
        }
        // each vector will be sorted if you want to
        sort(rand_vec.begin(), rand_vec.end());
        // push each of the 'num_of_rand_vectors'-th vectors into vec
        vec.push_back(rand_vec);
    }
}

void main() {

    srand(static_cast<unsigned int>(time(NULL)));

    // input vector containing random sorted vectors
    vector<vector<int>> vec;
    generate_random_vectors(3, vec);
}
Tributary answered 3/1, 2016 at 14:11 Comment(1)
Hardly related to the original post at all.Finished

© 2022 - 2024 — McMap. All rights reserved.