Является ли std::string size() операцией O (1)?

Является ли std::string size() операцией O (1)?

Реализация STL, которую я использую, является встроенной в VС++

Ответ 1

Если вы спрашиваете, имеет ли MSVC реализация string :: size() постоянную сложность, тогда ответ - да. Но Дон Уэйкфилд упомянул таблицу 65 в 23.1 стандарта C++, где говорится, что сложность size() должна соответствовать тому, что сказано в "Примечании A". Примечание А говорит:

Эти записи, помеченные '' (Примечание A), должны иметь постоянную сложность.

Однако это не означает, что эти записи должны иметь постоянную сложность. Стандарты используют очень специфическую терминологию, и "должен" означает, что это не обязательно.

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

Таким образом, вы не можете полагаться на то, что size() имеет постоянную сложность, но я, честно говоря, не уверен, есть ли реализации, в которых нет постоянной string::size().

Ответ 2

Вот простой способ ответить на этот вопрос для msvС++.

Напишите код в проекте:

string happy;
happy.size();

Вызов Hilight.size, щелкните правой кнопкой мыши, перейдите к определению.

В моей установке (vs2005sp1) это отправляет мне xstring: 1635, который выглядит следующим образом:

size_type __CLR_OR_THIS_CALL size() const
    {   // return length of sequence
    return (_Mysize);
    }

Итак, похоже, что в строке есть член с именем _Mysize, и он просто возвращает это.

Другими словами, это реализация O (1).

Ответ 3

Да, std::string:: size() - O (1).

Ответ 4

См. таблицу 65 в разделе 23.1 стандарта. "a.size()" указан как "(Примечание A)", в котором говорится, что "те записи... должны иметь постоянную сложность".

В разделе 21.3 говорится, что строки соответствуют требованиям последовательности (23.1), ipso facto, size() - постоянное время.

Ответ 5

Для строки операция size() должна быть постоянной для всех реализаций строк, которые не используют веревки (1). В стандарте нет явного требования, для которого операция должна быть O(1), ближайшим является общее требование, чтобы size() должно быть постоянным временем, но это оставляет место для любой другой меры сложности.

Так почему же это O (1)?

Это происходит из-за того, что размер не может быть рассчитан из содержимого самой строки. В то время как в C вы используете терминатор NUL для определения конца строки, в С++ NUL такой же допустимый, как и любой другой символ в строке. Поскольку размер строки не может быть рассчитан из содержимого (2) он должен обрабатываться извне, независимо от фактического размера строки.

(1) Стандарт С++ 03 позволяет реализации использовать канаты в качестве реализации для строк, но факт в том, что ни одна из существующих реализаций стандартных библиотек их не использует.

(2) Если в реализации используются веревки, операция может зависеть от размера с помощью количества блоков, из которых была построена веревка, если блоки были связаны через связанный список или аналогичные конструкции, или если им разрешено иметь разные размеры. Но канаты не используются в какой-либо стандартной реализации библиотеки, о которой я знаю.

Ответ 6

Производительность гарантируется STL как минимум для O (N) для контейнеров, однако многие контейнеры, включая std::string, могут реализовать это как O (1) и будут. Обычно он либо возвращает простую переменную, либо делает что-то вроде _End - _Begin и возвращает это.

Ответ 7

size_type __CLR_OR_THIS_CALL size() const

{   // return length of sequence

    return (_Mysize);

}

Так что в конце концов это может быть так, но вы никогда не можете быть уверены.