Преобразование даты в числовой формат
Задача
Условие и цель задачи. Пользователь вводит дату в формате ‘dd.mm.yyyy’, которая присваивается строчной переменной s. Необходимо преобразовать строку в запись d, имеющую три числовых поля – day, month, year.
Решение
Алгоритм решения задачи:
Алгоритмы преобразования строчного представления даты в численное могут использоваться в программах, которые выполняют какие-либо вычисления, связанные с датами.
Мы не будем писать сразу наиболее эффективную и короткую программу. Сначала алгоритм решения будет достаточно прозрачным и простым.
Программа на языке Паскаль:
Алгоритм 1. Линейная программа
Введенная пользователем дата находится в строчной переменной s.
Извлечение любого символа из строки производится так же, как получение элемента массива по его индексу. Например, s[1] приведет к извлечению первого символа сроки. Можно даже извлечь срез: s[1..2] извлечет первые два символа. Однако как их преобразовать в число?
Функция ord возвращает порядковый номер переданного ей аргумента. Если ей передать символ, то она вернет его номер в таблице символов. Это будет величина целого типа. Например, символ ‘0’ (ноль) может быть 48-м. Поэтому ord(‘0’) вернет 48. Далее номера цифр идут по порядку друг за другом: ‘1’ – 49, ‘2’ – 50, ‘3’ – 51 и т.д.
Чтобы перевести символьное представление цифры (например, ‘7’) в число (7), достаточно выполнить такое выражение: ord(‘7’) – ord(‘0’). Разница номеров между данными символами как раз составляет семь единиц. Таким образом, мы можем перевести символьное представление цифры в число.
Следующая проблема заключается в том, что числа в дате двузначные (день и месяц) и четырехзначные (год). Мы же получили значение только отдельных цифр. Однако, имея цифры и зная их позицию в числе, нетрудно вычислить само число. Например, если первое число 2 (десятки), а второе 4 (единицы), то получить 24 легко: 2 * 10 + 4. Год wxyz вычисляется по формуле w * 1000 + x * 100 + y * 10 + z.
Кроме того, следует не забыть пропустить точки в строке даты. Это символы под номерами 3 и 6. Они никакого участия в вычислениях принимать не должны.
type date = record year:1900..2050; month:1..12; day:1..31; end; var d: date; s: string; k,l,m,n: byte; begin write('Введите дату в формате dd.mm.yyy: '); readln(s); k := ord(s[1])-ord('0'); l := ord(s[2])-ord('0'); d.day := 10 * k + l; k := ord(s[4])-ord('0'); l := ord(s[5])-ord('0'); d.month := 10 * k + l; k := ord(s[7])-ord('0'); l := ord(s[8])-ord('0'); m := ord(s[9])-ord('0'); n := ord(s[10])-ord('0'); d.year := 1000 * k + 100 * l + 10 * m + n; writeln(d.day); writeln(d.month); writeln(d.year); readln end.
Алгоритм 2. Использование цикла и массива
Как можно заметить, слишком много раз в предыдущей программе выполняется выражениеord(s[цифра])-ord('0'). Подобные действия лучше выполнять в цикле, а результат помещать не в переменные, а массив.
Требуется преобразовать в цикле все символы строки, за исключением 3-го и 6-го (тех, которые являются точкой), и заполнить массив.
type date = record year:1900..2050; month:1..12; day:1..31; end; var d: date; s: string; i, j: byte; a: array [1..8] of byte; begin write('Введите дату в формате dd.mm.yyy: '); readln(s); i := 1; for j := 1 to 10 do if s[j] <> '.' then begin a[i] := ord(s[j]) - ord('0'); i := i + 1 end; d.day := 10 * a[1] + a[2]; d.month := 10 * a[3] + a[4]; d.year := 1000 * a[5] + 100 * a[6] + 10 * a[7] + a[8]; writeln(d.day); writeln(d.month); writeln(d.year); readln end.
Алгоритм 2. Быстрое решение
На самом деле не обязательно использовать массив, цикл и даже лишние переменные. Все делается гораздо проще, однако выражения получаются достаточно длинными и могут быть непонятны для начинающих.
type date = record year:1900..2050; month:1..12; day:1..31; end; var d: date; s: string; begin write('Введите дату в формате dd.mm.yyy: '); readln(s); d.day := 10 * (ord(s[1])-ord('0')) + (ord(s[2])-ord('0')); d.month := 10 * (ord(s[4])-ord('0')) + (ord(s[5])-ord('0')); d.year := 1000 * (ord(s[7])-ord('0')) + 100 * (ord(s[8])-ord('0')); d.year := d.year + 10 * (ord(s[9])-ord('0')) + (ord(s[10])-ord('0')); writeln(d.day); writeln(d.month); writeln(d.year); readln end.
Комментарии
Могу предложить ещё подобный…