C++. Сборник рецептов - [73]

Шрифт
Интервал

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

Если вы не знакомы с >map, то вам стоит узнать про него, >map — это шаблон класса контейнера, который является частью STL. Он хранит пары ключ-значение в порядке, определяемом >std::less или вашей собственной функцией сравнения. Типы ключей и значений, которые можно хранить в нем, зависят только от вашего воображения. В этом примере мы просто сохраняем >string и >int.

В строке 6 я для упрощения читаемости кода использовал >typedef.

>typedef map StrIntMap;

Таким образом, >StrIntMap — это >map, который хранит пары string/int. Каждая >string — это уникальное слово именно по этой причине я использую ее как ключ, — которое было прочитано из входного потока, а связанное с ней >int — это число раз, которое это слово встретилось. Все, что осталось, — это прочитать все слова по одному, добавить их в map, если их там еще нет, и увеличить значение счетчика, если они там уже есть.

Это делает >countWords. Основная логика кратка.

>while (in >> s) {

> ++words[s];

>}

>operator>> читает из левого операнда (>istream) непрерывные отрезки, не содержащие пробелов, и помещает их в правый операнд (>string). После прочтения слова все, что требуется сделать, — это обновить статистику в >map, и это делается в следующей строке.

>++words[s];

>map определяет >operator[], позволяющий получить значение данного ключа (на самом деле он возвращает ссылку на само значение), так что для его инкремента просто инкрементируется значение, индексируемое с помощью заданного ключа. Но здесь могут возникнуть небольшие осложнения. Что, если ключа в map еще нет? Разве мы не попытаемся увеличить несуществующий элемент, и не обрушится ли программа, как в случае с обычным массивом? Нет, >map определяет >operator[] не так, как другие контейнеры STL или обычные массивы.

В >map operator[] делает две вещи: если ключ еще не существует, он создает значение, используя конструктор типа значения по умолчанию, и добавляет в >map эту новую пару ключ/значение, а если ключ уже существует, то никаких изменений не вносится. В обоих случаях возвращается ссылка на значение, определяемое ключом, даже если это значение было только что создано конструктором по умолчанию. Это удобная возможность (если вы знаете о ее существовании), так как он устраняет необходимость проверки в клиентском коде существования ключа перед его добавлением.

Теперь посмотрите на строки 32 и 33. Итератор указывает на члены, которые называются >first и >second — что это такое? >map обманывает вас, используя для хранения пар имя/значение другой шаблон класса: шаблон класса >pair, определенный в > (уже включенный в >). При переборе элементов, хранящихся в >map, вы получите ссылки на объекты >pair. Работа с >pair проста. Первый элемент пары хранится в элементе >first, а второй хранится, естественно, в >second.

В примере 4.27 я для чтения из входного потока непрерывных фрагментов текста использую >operator>>, что отличается от некоторых других примеров. Я делаю это для демонстрации того, как это делается, но вам почти наверняка потребуется изменить его поведение в зависимости от определения «слова» текстового файла. Например, рассмотрим фрагмент вывода, генерируемого примером 4.27.

>with присутствует 5 раз.

>work присутствует 3 раз.

>workers присутствует 3 раз.

>workers, присутствует 1 раз.

>years присутствует 2 раз.

>years, присутствует 1 раз.

Обратите внимание, что точки в конце слов рассматриваются как части слов. Скорее всего, вам потребуется с помощью функций проверки символов из > и > изменить определение слова так, чтобы оно означало только буквенно-цифровые символы, как это сделано в рецепте 4.17.

Смотри также

Рецепт 4.17 и табл. 4.3.

4.19. Добавление полей в текстовый файл

Проблема

Имеется текстовый файл, и в нем требуется сделать поля. Другими словами, требуется сдвинуть обе стороны каждой строки, содержащей какие-либо символы, так, чтобы длина всех строк стала одинаковой.

Решение

Пример 4.28 показывает, как добавить в файл поля с помощью потоков, >string и шаблона функции >getline.

Пример 4.28. Добавление полей в текстовый файл

>#include

>#include

>#include

>#include


>using namespace std;


>const static char PAD_CHAR = '.';


>// addMargins принимает два потока и два числа. Потоки используются для

>// ввода и вывода. Первое из двух чисел представляет

>// ширину левого поля (т.е. число пробелов, вставляемых в

>// начале каждой строки файла). Второе число представляет

>// общую ширину строки.

>void addMargins(istream& in, ostream& out,

> int left, int right) {

> string tmp;

> while (!in.eof()) {

>  getline(in, tmp, '\n'); // getline определена

>                          // в

>  tmp.insert(tmp.begin(), left, PAD_CHAR);

>  rpad(tmp, right, PAD_CHAR); // rpad из рецепта

>                              // 4.2

>  out << tmp << '\n';

> }

>}


>int main(int argc, char** argv) {

> if (argc < 3)

>  return(EXIT_FAILURE);

> ifstream in(argv[1]);

> ofstream out(argv[2]);

> if (!in || !out)

>  return(EXIT_FAILURE);

> int left = 8;

> int right = 72;

> if (argc == 5) {

>  left = atoi(argv[3]);

>  right = atoi(argv[4]);

> }

> addMargins(in, out, left, right);


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.