Подтвердить что ты не робот

Как случайным образом назначить вектор в С++?

Я новичок в С++, и мне постоянно говорят использовать std::vector вместо new[].

Я пытаюсь достичь этой функциональности, где я знаю размер вектора и хочу назначать ему случайным образом (не последовательно).

Однако при выполнении этой программы моя программа завершается без вывода ошибок, поэтому я не уверен.

vector<string> v1;
v1.resize(2);
v1.insert(v1.begin() + 1, "world");
v1.insert(v1.begin() + 0, "world");

cout << v1.at(1) << endl;
4b9b3361

Ответ 1

Не сдавайтесь, это проще, чем

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";

cout << v1[1] << endl;

vector::insert - это когда вы хотите добавлять элементы к своему вектору, а не когда вы хотите заменить те, которые уже есть, vector::insert изменяет размер вектора другими словами.

Ответ 2

Сначала вы измените его размер на две пустые строки:

{"", ""}

Затем вы вставляете "world" перед begin() + 1 или вторым элементом:

{"", "world", ""}

Затем вы вставляете "world" до begin() или 1-го элемента:

{"world", "", "world, ""}

Затем вы получаете доступ к 2-му элементу с помощью v1.at(1) и получите пустую строку.

Предположительно, вы не хотите std::vector::insert, который вставляет новые элементы между существующими элементами. Вы хотите сделать это так же, как с массивами, operator[]:

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";
cout << v1.at(1) << endl;

Ответ 3

Чтобы случайно назначить

Просто используйте индекс (очевидно, убедитесь, что он < size)

v1[index] = value;

Случайно вставить (проверить этот индекс < size)

v1.insert(v1.begin() + index, value);

Чтобы последовательно вставить в конец/добавить (нет необходимости в индексе, ваше значение будет вставлено в конце вектора)

v1.push_back(value);

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

Ответ 4

Ваша программа работает правильно. Ваша ошибка в логике вашего кода.

Вставка не меняет строку, хранящуюся в индексе 1. Она помещает строку в позицию 1 и перемещает все индексы после 1 вправо.

start               first insert            second insert 
("","")      ->   ("", "world, "")    ->  ("world","","world","")

Итак, когда вы печатаете v1.at(1), вы печатаете пустую строку.

Чтобы устранить проблему, вы хотели бы использовать:

v1.at(1)="world"
v1.at(0)="world"

- или -

v1[1] ="world"
v1[0] ="world"

Два решения эквивалентны, однако второй не будет проверять границы. Первый будет вызывать ошибку, если есть ошибка за пределами границ. Это не имеет значения, если вы можете гарантировать, что никогда не будете индексироваться за пределы.

Ответ 5

Как и многие из них, вы можете просто использовать operator[] для переназначения старых значений, учитывая, что вы уже оценили вектор или заполнили его другими значениями. Если ваш массив всегда будет иметь фиксированный размер, вы можете использовать std::array, который должен обеспечить повышение производительности, при жертве возможности изменять размер массива или определять его размер во время выполнения.

std::array<std::string,2> a1;
a1[0] = "world";
a1[1] = "world2";
std::cout<<a1.at(1)<<std::endl; //outputs world2

Обратите внимание, что размер должен быть статическим, поэтому вы не можете сделать что-то вроде этого:

int numStrings;
std::cin>>numStrings;
std::array<std::string,numStrings> a2; //ERROR

К сожалению, я не думаю, что есть какой-либо способ инициализации std::array без конструктора по умолчанию, кроме использования списка инициализации.

struct T
{
   T(std::string s):str(s){} //no default constructor
   std::string str;
}
std::array<T,2> a3 = {T(""), ""}; //you can use a conversion constructor implicitly

Очевидно, это нецелесообразно, если вы хотите массив с значительным количеством объектов.