Резерв вектора STL () и копия ()

is возвратится True, если две переменные укажут на тот же объект, ==, если объекты, упомянутые переменными, равны.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:] # Make a new copy of list `a` via the slice operator, and assign it to variable `b`
>>> b is a
False
>>> b == a
True

В Вашем случае, второй тест только работает, потому что кэши Python маленькие целочисленные объекты, который является деталью реализации. Для больших целых чисел это не работает:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

то же сохраняется для строковых литералов:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

см. этот вопрос также.

18
задан Jon Seigel 15 May 2010 в 20:59
поделиться

4 ответа

Как отмечалось в других ответах и ​​комментариях, для этого вам следует просто использовать встроенные функции вектора. Но:

Когда вы резервируете () элементов, вектор будет выделять достаточно места для (по крайней мере?) Такого количества элементов. Элементы не существуют в векторе, но память готова к использованию. Тогда это, возможно, ускорит push_back () , потому что память уже выделена.

Когда вы resize () вектор, он выделит достаточно места для этих элементов, , но также добавьте их в вектор .

Итак, если вы измените размер вектора до 100, вы сможете получить доступ к элементам 0–99, но если вы зарезервируете 100 элементов, они еще не вставлены, просто готовы к использованию .

Вам нужно что-то вроде этого:

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), std::back_inserter(vec2));

std :: back_inserter определено в < iterator>

26
ответ дан 30 November 2019 в 05:40
поделиться

Если векторы одного типа, используйте построение копии или присваивание копии:

vec2(vec1);
vec2 = vec1;

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

vec2(vec1.begin(), vec1.end()); // range-based constructor

vec2.assign(vec1.begin(), vec1.end()); // range-based assignment

Если вы настаиваете на выполнении этого с помощью std :: copy , правильный метод:

copy(vec1.begin(), vec1.end(), back_inserter(vec2));

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

В книге Эффективный STL Скотт Мейерс утверждает, что почти все случаи использования std :: copy для вставки следует заменить функциями-членами на основе диапазона. Предлагаю вам взять копию, это отличная ссылка!

33
ответ дан 30 November 2019 в 05:40
поделиться

Почему бы и нет: vec2 = vec1; ?

20
ответ дан 30 November 2019 в 05:40
поделиться

Изменить резерв на resize ():

vec2.resize(vec1.size(), '\0');
copy(vec1.begin(), vec1.end(), vec2.begin());

Я считаю, что это то исправление, которое вам нужно.

Я не могу дать вам очень хорошее описание разницы, но в основном резерв ( ) проверяет, достаточно ли места, а resize () действительно что-то вставляет туда.

3
ответ дан 30 November 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: