Проверка, является ли вектор пустым - PullRequest
37 голосов
/ 05 октября 2010

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

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

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

Подход 1

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

Подход 2

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

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

Ответы [ 8 ]

40 голосов
/ 05 октября 2010

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

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

8 голосов
/ 05 октября 2010

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

8 голосов
/ 05 октября 2010

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

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

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

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

.....

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

3 голосов
/ 05 октября 2010

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

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

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

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

2 голосов
/ 04 июня 2015

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

2 голосов
/ 05 октября 2010

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

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

1 голос
/ 05 октября 2010

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

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

?

0 голосов
/ 05 октября 2010

Перейти на пустой ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...