Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

4.4. Получение длины строки

Проблема

Требуется узнать длину строки.

Решение

Используйте метод

length
класса
string
.

std::string s = "Raising Arizona";

int i = s.length;

Обсуждение

Получение длины строки — это тривиальная задача, но она является хорошей возможностью обсудить схему размещения

string
(как узких, так и широких символов).
string
, в отличие от массивов
строк, завершаемых нулем, в С являются динамическими и увеличиваются по мере надобности. Большая часть реализаций стандартной библиотеки начинают с относительно низкой емкости и увеличивают ее в два раза каждый раз, когда достигается предел. Знание того, как анализировать этот рост, если и не точного алгоритма, помогает диагностировать проблемы производительности, связанные со строками.

Символы в

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

Определить размер буфера (не число символов, в нем содержащихся, а его максимальный размер) можно с помощью метода

capacity
. Если требуется вручную установить емкость и избежать ненужных копирований буфера, используйте метод reserve и передайте ему числовой аргумент, указывающий требуемый размер буфера. Также имеется максимально возможный размер буфера, получить который можно с помощью вызова
max_size
. Это все можно использовать, чтобы посмотреть на расходование памяти в данной реализации стандартной библиотеки. Посмотрите на пример 4.9, показывающий, как это сделать.

Пример 4.9. Длина строки и ее емкость

#include <string>

#include <iostream>

using namespace std;

int main {

 string s = "";

 string sr = "";

 sr.reserve(9000);

 cout << "s.length = " << s.length << '\n';

 cout << "s.capacity = " << s.capacity << '\n';

 cout << "s.max.size = " << s.max_size << '\n';

 cout << "sr.length = " << sr.length << '\n';

 cout << "sr.capacity = " << sr.capacity << '\n';

 cout << "sr.max_size = " << sr.max_size << '\n';

 for (int i = 0; i < 10000; ++i) {

if (s.length == s.capacity) {

cout << "s достигла емкости " << s.length << увеличение... \n";

}

if (sr.length == sr.capacity) {

cout << "sr достигла емкости " << sr.length << ", увеличение...\n";

}

s += 'x';

sr += 'x';

 }

}

При

использовании Visual C++ 7.1 вывод выглядит так.

s.length = 0

s.capacity = 15

s.max_size = 4294967294

sr.length = 0

sr.capacity = 9007

sr.max_size = 4294967294

s достигла емкости 15, увеличение...

s достигла емкости 31, увеличение...

s достигла емкости 47, увеличение...

s достигла емкости 70, увеличение...

s достигла емкости 105, увеличение...

s достигла емкости 157, увеличение...

s достигла емкости 235, увеличение...

s достигла емкости 352, увеличение...

s достигла емкости 528, увеличение...

s достигла емкости 792, увеличение...

s достигла емкости 1188, увеличение...

s достигла емкости 1782, увеличение...

s достигла емкости 2673, увеличение...

s достигла емкости 4009, увеличение...

s достигла емкости 6013, увеличение...

sr достигла емкости 9007, увеличение...

s достигла емкости 9019, увеличение...

Здесь происходит то, что буфер строки заполняется по мере добавления в него символов. Если буфер оказывается полон (т.е. длина = емкость), выделяется новый буфер, и символы оригинальной строки и новый добавляемый символ (или символы) копируются в этот новый буфер,

s
начинает заполняться с емкости 15 (зависит от компилятора), а затем увеличивается каждый раз примерно на 50%.

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

reserve
. Также следует провести эксперименты с имеющейся реализацией стандартной библиотеки и посмотреть, как она выполняет увеличение строк.

Кстати, когда потребуется узнать, пуста ли строка, не сравнивайте ее размер с нулем, а просто вызовите метод

empty
. Это метод, который возвращает истину, если длина строки равна нулю.

4.5. Обращение строк

Проблема

Требуется обратить (реверсировать) строку.

Решение

Чтобы обратить строку «на месте», не используя временной строки, используйте шаблон функции reverse из заголовочного файла

<algorithm>
:

std::reverse(s.begin, s.end);

Обсуждение

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

В случае, если требуется скопировать строку в другую строку, но в обратном порядке символов, используйте реверсивные итераторы, как здесь:

std::string s = "Los Angeles";

Поделиться:
Популярные книги

Жалкая

Макинтайер Эмили
3. Долго и Несчастливо
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Жалкая

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Академия проклятий. Книги 1 - 7

Звездная Елена
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Академия проклятий. Книги 1 - 7

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сердце для стража

Каменистый Артем
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Сердце для стража

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Маленькая слабость Дракона Андреевича

Рам Янка
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Маленькая слабость Дракона Андреевича