Читаем Программирование полностью

{year 2000

{ month feb (1 1 68 ) (2 3 66.66 ) ( 1 0 67.2)}

{month dec (15 15 –9.2 ) (15 14 –8.8) (14 0 –2) }

  Этот формат довольно своеобразен. Форматы записи файлов часто оказываются довольно специфическими. В промышленности наблюдается тенденция к широкому использованию все более упорядоченных и иерархически структурированных файлов (например, HTML и XML), но в действительности мы по-прежнему редко можем контролировать формат файла, который необходимо прочитать. Файлы таковы, каковы они есть, и нам нужно их прочитать. Если формат слишком неудачен или файлы содержат много ошибок, можем написать программу преобразования формата в более подходящий. С другой стороны, мы, как правило, имеем возможность выбирать представление данных в памяти в удобном для себя виде, а при выборе формата вывода часто руководствуемся лишь собственными потребностями и вкусом.

Предположим, данные о температуре записаны в указанном выше формате и нам нужно их прочитать. К счастью, формат содержит автоматически идентифицируемые компоненты, такие как годы и месяцы (немного напоминает форматы HTML и XML). С другой стороны, формат отдельной записи довольно неудобен. Например, в ней нет информации, которая могла бы нам помочь, если бы кто-то перепутал день месяца с часом или представил температуру по шкале Цельсия, хотя нужно было по шкале Фаренгейта, и наоборот. Все эти проблемы нужно как-то решать. 

<p id="AutBody_Root189"><strong>10.11.1. Представление в памяти</strong></p>

 Как представить эти данные в памяти? На первый взгляд, необходимо создать три класса, Year, Month и Reading, точно соответствующие входной информации. Классы Year и Month очевидным образом могли бы оказаться полезными при обработке данных; мы хотим сравнивать температуры разных лет, вычислять среднемесячные температуры, сравнивать разные месяцы одного года, одинаковые месяцы разных лет, показания температуры с записями о солнечном излучении и влажности и т.д. В принципе классы Year и Month точно отображают наши представления о температуре и погоде: класс Month содержит ежемесячную информацию, а класс Year — ежегодную. А как насчет класса Reading ? Это понятие низкого уровня, связанное с частью аппаратного обеспечения (сенсором). Данные в классе Reading (день месяца, час и температура) являются случайными и имеют смысл только в рамках класса Month. Кроме того, они не структурированы: никто не обещал, что данные будут записаны по дням или по часам. В общем, для того чтобы сделать с данными что-то полезное, сначала их необходимо упорядочить. Для представления данных о температуре в памяти сделаем следующие предположения.

• Если есть показания для какого-то месяца, то их обычно бывает много.

• Если есть показания для какого-то дня, то их обычно бывает много.

В этом случае целесообразно представить класс Year как вектор, состоящий из 12 объектов класса Month, класс Month — как вектор, состоящий из 30 объектов класса Day, а класс Day — как 24 показания температуры (по одному в час). Это позволяет просто и легко манипулировать данными при решении самых разных задач. Итак, классы Day, Month и Year — это простые структуры данных, каждая из которых имеет конструктор. Поскольку мы планируем создавать объекты классов Month и Day как часть объектов класса Year еще до того, как узнаем, какие показания температуры у нас есть, то должны сформулировать, что означает “пропущены данные” для часа дня, до считывания которых еще не подошла очередь.

const int not_a_reading = –7777; // ниже абсолютного нуля

Аналогично, мы заметили, что часто в течение некоторых месяцев не производилось ни одного измерения, поэтому ввели понятие “пропущен месяц”, вместо того чтобы проверять пропуски для каждого дня.

const int not_a_month = –1;

Три основных класса принимают следующий вид:

struct Day {

  vector hour;

  Day(); // инициализируем массив hour значениями "нет данных"

};

Day::Day()

    : hour(24)

{

  for (int i = 0; i

}

struct Month {     // месяц

  int month;       // [0:11] январю соответствует 0

  vector day; // [1:31] один вектор для всех данных по дням

  Month()          // не больше 31 дня в месяце (day[0]

                   // не используется)

    :month(not_a_month), day(32) { }

};

struct Year {           // год состоит из месяцев

  int year;             // положительный == н.э.

  vector month;  // [0:11] январю соответствует 0

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже