2015-03-21 2 views
-5

Я нашел людей, предлагая не использовать STRLEN() аргументируя, что его временная сложность не O (1) .Than, что я должен использовать в массив символов, чтобы узнать размер в хорошей временной сложности, за исключениемКакова может быть альтернатива strlen()?

 s[i]!='\0' 
+5

'std :: string :: size()' –

+3

Вы не использовали бы массив символов .... и ваш пример не работает для определения размера строки C. Почему вы используете 'char []' для строк в C++? –

+2

Проблема не в функции (которая реализована так эффективно, как может быть), а в стиле кодирования, что делает его частое использование необходимым. Как отмечали другие, помните длину строки. В C++ используйте 'std :: string'. (Вы должны использовать его и по другим причинам.) – 5gon12eder

ответ

3

Если вы собираетесь использовать массив C-стиля char, то я не думаю, что есть какой-либо способ выработать длину, кроме как зацикливаться до тех пор, пока вы не дойдете до конца. Вы можете сделать это самостоятельно или позвонить по телефону strlen.

Однако, как вы отметили свой вопрос с , вы должны использовать std::string вместо этого, то вы можете использовать метод length (или, что эквивалентно, size) вместо этого.

+0

большое спасибо господину. –

1

Если вы используете C++, не используйте строки C-стиля (то есть char*). Вместо этого используйте std::string. Для стандарта C++ std::string::size имеет сложность O (1). Это может быть достигнуто путем вычисления длины строки один раз и сохранения ее в элементе данных (и обновления при изменении длины строки).

Однако, если мы говорим о С, то нет другого пути. C использует строки с нулевым символом.

Интересно, что некоторые языки (например, Pascal) реализуют строки по-разному. Вместо использования строк с нулевым завершением (например, C) они выбирают строки с префиксом длины. Это означает, что каждая строка имеет длину, записанную в начале. У этого есть некоторые проблемы, например, теперь вы тратите дополнительные байты для хранения счетчика длины, вы можете хранить только конечное количество символов в строке (например, если вы используете 2 байта для длины, ваша строка может содержать не более 2^16 символов), а работа с подстроками становится хором.

+1

Ничего не мешает вам кэшировать длину строки в отдельной переменной (желательно инкапсулироваться в некоторую 'struct string {char * data; size_t length; size_t capacity;};'), даже если вы кодируете в C. Некоторая библиотека функции могут не позволить вам передать эту дополнительную информацию. – 5gon12eder

+0

Да, это правда. Однако, как вы сказали, библиотеки не будут принимать настраиваемую структуру (скорее всего, они работают с просто «char *», если они «завершаются \ 0»), и они могут повторно пересчитать длину строки. Не существует 100% уверенного способа избежать дополнительной работы. – nicebyte

0

Как кто-то уже упоминалось в комментариях, вы можете легко иметь структуру, которая содержит длину и данные, такие как:

struct string{ 
    char * Data; 
    int Length; 
} 

Вы могли бы также иметь Resizeable строки, для которых вы также хотите, чтобы удерживать вместимость.

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

0

Если вы используете char[], тогда вы можете использовать sizeof(str) - 1. Примечание: std::strlen(str), скорее всего, будет оптимизирован. Например, используя GCC 4.9.2 с -O2, следующие коды:

std::cout << sizeof("hello") - 1; 
std::cout << std::strlen("hello"); 

результат в этой сборке:

[...] 
movl $5, %esi 
[...] 

Вы должны использовать std::string в любом случае.std::string::size и std::string::length оба имеют постоянную сложность, так как она может быть реализована как это (libstdC++):

size_type 
    size() const _GLIBCXX_NOEXCEPT 
    { return _M_rep()->_M_length; } 

Как и другие предложили, вы можете сохранить длину в переменной и свести к минимуму вызовы std::strlen. В общем, это пахнет как случай преждевременной оптимизации. Стандартная библиотека C++ - лучший выбор.

Смежные вопросы