Заполнить вектор случайными числами С++

У меня есть вектор, который я пытаюсь заполнить случайными числами. Однако я продолжаю сталкиваться с проблемой, что вектор в основном выводит 0 каждый раз, когда я его запускаю (он никогда не должен выводить 0). Что я делаю неправильно в своем коде, написанном ниже, чтобы он выводил 0 (он выводит 0 больше, чем любое другое число):

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;
    }

Я новичок и долгое время не занимался программированием на С++, поэтому я не уверен, что делает мой код неисправным. Если бы кто-то мог объяснить, что я сделал неправильно, это было бы очень признательно.


person Valrok    schedule 02.02.2014    source источник
comment
myVector[b] должен быть myVector[i]   -  person atablash    schedule 03.02.2014
comment
Или, возможно, это должно быть myVector.back()   -  person paddy    schedule 03.02.2014


Ответы (7)


Вы вызываете неправильный индекс в своем векторе

Попробуйте сделать:

cout << myVector[i] << endl;

иначе вы рискуете убежать от конца вашей вершины в течение первых 20 или около того итераций.

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

person Serdalis    schedule 02.02.2014
comment
А, я подумал, что это будет что-то маленькое, чего я не видел. С точки зрения скорости, будет ли разница между использованием .back() или [i]? - person Valrok; 03.02.2014
comment
Вам нужно будет сравнить его, но я сильно подозреваю, что .back() быстрее и безопаснее. - person Serdalis; 03.02.2014
comment
@Valrok кстати, в будущем, если в вашем распоряжении будет реализация C++11, я настоятельно рекомендую использовать <random>. Это действительно решает множество проблем, таких как смещение по модулю. Посмотреть вживую - person WhozCraig; 03.02.2014
comment
@Valrok: Если вы включите оптимизацию, они, вероятно, будут одинаково быстрыми. Оптимизатор должен иметь возможность генерировать функционально идентичный код. - person MSalters; 03.02.2014

Вы можете использовать алгоритм std::generate для заполнения вектора из n элементов случайными числами.

В современном C++ рекомендуется не использовать начальные значения на основе времени и std::rand, а вместо этого использовать random_device для создания начального числа. Для программного движка всегда нужно указывать движок и дистрибутив. Подробнее...

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

using namespace std;

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

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

}

Если вы хотите переставить элементы диапазона в случайном порядке:

  std::shuffle(begin(vec), end(vec), mersenne_engine);
person Marko Tunjic    schedule 17.04.2014
comment
Вы должны привязать ссылку к mersenne_engine с помощью std::ref, иначе генерация нескольких векторов с одним и тем же генератором приведет к тому, что все векторы будут одинаковыми. см. соответствующий вопрос. - person zennehoy; 15.01.2018
comment
Еще одно предупреждение: random_device может быть вовсе не случайным! Например, GCC под Windows всегда выдает один и тот же результат для вашего опубликованного кода. - person zennehoy; 15.01.2018

А если просто:

#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);
person Martin.Martinsson    schedule 22.04.2018
comment
похоже, он заполнит его теми же значениями - person x4444; 08.12.2020
comment
@ x4444: На моей машине это работает после нескольких тестов. Может быть, поставить std::srand(unsigned(std::time(nullptr))); спереди. - person Martin.Martinsson; 08.12.2020

Просто добавлю свои 2 цента... Этот ответ похож на тот, который дал Marko Tunjic, но он не использует std::rand из C, но вместо этого есть функции C++11. Это позволяет вам использовать дистрибутив по вашему выбору, uniform_int_distribution в приведенном ниже примере.

#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";
    }
}
person Marek Kurdej    schedule 01.10.2015
comment
Вы говорите, что ответ Марко Тунжича использует std::rand в C? Не могли бы вы объяснить это подробнее для меня? - person John; 01.08.2021
comment
Раньше он использовал rand, когда я писал свой ответ. Взгляните на первую версию stackoverflow.com/revisions/23143753/1. - person Marek Kurdej; 02.08.2021

Вы вызываете неправильный индекс в своем векторе

cout << myVector[i] << endl;
person Khalil Ismail    schedule 02.02.2014

Непонятно, что вы пытаетесь сделать с циклом, код создает вектор случайного размера, заполненный случайными числами.

Вы выводите «myVector[b]», но «b» — это случайное значение, а не индекс только что добавленного числа. Вы могли бы просто:

cout << b << endl;

Но на самом деле вы должны определить размер вектора и просто получить доступ по индексу.

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"));
person Sanjaya R    schedule 02.02.2014
comment
Переменная над ней (a) намеренно представляет собой случайное число от 1 до 20, и я пытаюсь сделать вектор размером a, при этом каждый индекс имеет случайное число, равное ‹= a - person Valrok; 03.02.2014

cout << myVector[b] ?!

должно быть: cout << myVector[i];

person Tony Lim    schedule 02.02.2014