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

Проверка, свободен ли вектор

Предположим, что у меня есть std::vector say Vector

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

Какой подход лучше

Подход 1

if (Vector.size() == 0){ /* operations */ }

Подход 2

if (Vector.empty()) { /* operations */ }

Какой подход лучше, 1 или 2?

4b9b3361

Ответ 1

v.size() == 0 говорит: "Я сравниваю размер", но делает это, чтобы проверить, пустой ли контейнер. Там небольшой алгоритм для переваривания (очень маленький, поскольку он состоит только из сравнения), прежде чем вы знаете, что он делает.
OTOH, v.empty() выполняет именно то, что он говорит: он проверяет, является ли v пустым.
Из-за этого я явно предпочитаю # 2, так как он делает то, что он говорит. Вот почему empty() был изобретен, в конце концов.

Но есть и алгоритмическая причина, чтобы предпочесть empty(): если кто-то позже изменит std::vector на std::list, v.size() может иметь O (n). (В С++ 03 он гарантированно равен O (1) для std::vector, но не для std::list. Согласно комментарию Джеймса на ответ Prasoon, это будет O (1) для всех контейнеров в С++ 1x.)

Ответ 2

Я бы сказал, утверждать, что нет 2, поскольку метод empty() был намеренно разработан, чтобы проверить, свободен ли вектор. Вы также можете проверить эффективность обоих подходов, а затем решить, какой из них лучше.

Ответ 3

Подход (2) был бы лучше, потому что empty() всегда работает в постоянное время [т.е. O (1)] независимо от контейнера тип.

size() тоже работает в O(1) [для std::vector], хотя он может выполняться в O(n) для std:list [это реализация определена как честная]

В Effective STL [Пункт 4] Скотт Мейерс говорит

Вы должны предпочесть конструкцию с использованием пустого, и причина проста: пустая - это операция с постоянным временем для всех стандартных контейнеров, но для некоторых реализаций списка, размер занимает линейное время.

.....

Независимо от того, что происходит, вы не ошибетесь, если вы вызываете пустое, а не проверяете на см., если size() == 0. Поэтому вызывается пустым, когда вам нужно знать, имеет ли контейнер нулевые элементы.

Ответ 4

Обычно вектор внутренне реализуется как указатель на динамически распределенный массив и элементы данных, содержащие capacity и size вектора. size вектора - это действительное количество элементов, а емкость относится к размеру динамического массива.

Учитывая эту реализацию, функция-член size() будет просто элементом getter для члена size.

empty() вернет результат сравнения size == 0.

Итак, обе одинаково эффективны O(1), но рекомендуется empty(), если вы хотите проверить, свободен ли вектор. Потому что это функция. Это упростит чтение кода.

Ответ 5

Если вы новичок в программировании, используйте тот, который имеет больше значения для вас. Например, если == 0 более значим для вас, чем .empty(), используйте это.

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

Ответ 6

На самом деле vector.empty() и vector.size() == 0 делают то же самое.  empty сравнивает начало и конец и возвращает true, если они одинаковы, размер вычисляет начало, а затем возвращает 0, если он пуст для этого, делая то же самое, используя другой расчет.

Ответ 7

Просто для удовольствия: почему бы и нет:

if(Vector.begin() == Vector.end())

?

Ответ 8

Go для empty().