Root /ArchiveAbout
()

Предшествующая и последующая дата

Предшествующая и последующая дата

Ниже дано решение двух схожих за смыслом задач на использование оператора выбора Case. Первая задача – нахождение даты, предшествовавшей указанной (для невисокосного года). Вторая – нахождение даты, которая следует за указанной. Условие невисокосного года указывать нужно, поскольку в противном случае код несколько усложняется.

Идея решения заключается в следующем. Во-первых, надо сгруппировать разные месяцы так, чтобы вместе оказались месяцы с равным количеством дней и это упростит проверку, во-вторых, проверять отдельно: 1) только 1-е число и остальную часть месяца (в случае предшествующей даты); 2) только последнее число и остальную часть (в случае следующей даты). Поскольку перед 1-м числом стоит последнее число предыдущего месяца, а за последним числом идет 1-е число следующего месяца, то эти случаи надо рассматривать отдельно.

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

Сase8. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, предшествующей указанной.

var
  D, M: byte;

begin
  { ВВОДИМ ДЕНЬ И МЕСЯЦ: }
  write('D = ');
  readln(D); { <-- Вводим значение дня }
  write('M = ');
  readln(M); { <-- Вводим значение месяца }
  writeln;
  { Проверяем 1-й день: }
  if D = 1 then begin
    { Находим последний день предшествующего месяца: }
    case M of
     { Для 1-го дня 3-го месяца предшествующим 
     является 28-й день: }
      3: D := 28;

     { Для 1-го дня 5-го, 7-го, 10-го и 12-го месяцев
     предшествующим является 30-й день: }
      5,7,10,12: D := 30;

     { Для 1-го дня 1-го, 2-го, 4-го, 6-го, 8-го, 9-го и
     11-го месяцев предшествующим является 31-й день: }
      1,2,4,6,8,9,11: D := 31
    end;
    { Номер предшествующего месяца. Для M = 1 он  равен 12,
    а для остальных M - 1. Можем использовать такую формулу: }
    M := (M + 10) mod 12 + 1
  end { Остальные дни уменьшаем на 1 (месяц не изменяется): }
  else dec(D);
  { ВЫВОДИМ РЕЗУЛЬТАТ с форматированием. Если число 
  имеет одну цифру, то в начале добавляем 0: }
  write('Предшествующая дата: ');
  if D < 10 then write('0', D, '.')
  else write(D, '.');
  if M < 10 then writeln('0', M)
  else writeln(M);
  readln
end.

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

* * *

Ниже представлено второе решение задачи Case8. Этот код включает в себя проверку правильности введенных данных, а также сообщение, если указанная дата не существует. Сначала вводим и проверяем данные (строки 10 – 29), а потом повторяем код первого варианта решения задачи (строки 32 – 59). В комментариях все пояснения.

var
  D, M, N: byte;
  f: boolean; { True - дата существует, False - не существует }

begin
  { ВВОДИМ ДЕНЬ И МЕСЯЦ. Для этого используем цикл: сначала 
  вводим значение дня и месяца, потом проверяем, существует 
  ли указанная дата; если дата не существует, то ввод 
  повторяется. Если дата существует, то выходим из цикла: }
  repeat
    write('D = ');
    readln(D); { <-- Вводим день }
    write('M = ');
    readln(M); { <-- Вводим месяц }
    { Проверяем, является ли введенная дата правильной: }
    f := true; { <-- Считаем, что введенная дата правильная }
    case M of
      { Второй месяц имеет 28 дней: }
      2: if (D < 1) or (D > 28) then f := false;

      4,6,9,11: { <-- Месяцы имеют 30 дней }
         if (D < 1) or (D > 30) then f := false;

      1,3,5,7,8,10,12: { <-- Месяцы имеют 31 день }
         if (D < 1) or (D > 31) then f := false
      else f := false { <-- M<1 или M>12 }
    end;
    if f = false then writeln(' Такой даты не существует!')
  until f; { <-- Выходим, если введенная дата правильная }
  writeln;
  { НАХОДИМ ПРЕДШЕСТВУЮЩУЮ ДАТУ }
  if D = 1 then begin { <-- Проверяем 1-й день: }
    { Находим последний день предшествующего месяца: }
    case M of
     { Для 1-го дня 3-го месяца предшествующим 
     является 28-й день: }
      3: D := 28;
      
     { Для 1-го дня 5-го, 7-го, 10-го и 12-го месяцев
     предшествующим является 30-й день: }
      5,7,10,12: D := 30;
      
     { Для 1-го дня 1-го, 2-го, 4-го, 6-го, 8-го, 9-го и
     11-го месяцев предшествующим является 31-й день: }
      1,2,4,6,8,9,11: D := 31
    end;
    { Номер предшествующего месяца. Для M = 1 он 
    равен 12, а для остальных M - 1: }
    if M = 1 then M := 12
    else M := M - 1
  end { Остальные дни уменьшаем на 1 (месяц не изменяется): }
  else dec(D);
  { ВЫВОДИМ РЕЗУЛЬТАТ. Если число имеет одну цифру, 
  то в начале добавляем 0: }
  write('Предшествующая дата: ');
  if D < 10 then write('0', D, '.')
  else write(D, '.');
  if M < 10 then writeln('0', M)
  else writeln(M);
  readln
end.

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

Сase9. Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести значения D и M для даты, следующей за указанной.

Эта задача отличается от предыдущей тем, что здесь надо искать следующую за указанной дату. Смысл решения в том, чтобы для каждого месяца посчитать количество в нем дней. Потом, если введенный день лежит в интервале от 1-го до предпоследнего, то увеличиваем его на 1. Если же мы ввели последний день месяца, то за ним наступает первое число, а месяц увеличивается на 1. Как и в первом решении зазания Case8, предполагается, что мы ввели правильную (существующую) дату для невисокосного года.

var
  D, M, CountDay: byte;

begin
  { ВВОДИМ ДЕНЬ И МЕСЯЦ: }
  write('D = ');
  readln(D);  { <-- Вводим значение дня }
  write('M = ');
  readln(M); { <-- Вводим значение месяца }
  writeln;
  { ПРОВЕРЯЕМ МЕСЯЦЫ ГОДА: }
  { Группируем месяцы по количеству дней: }
  case M of
    { Второй месяц имеет всего 28 дней: }
    2: CountDay := 28;

    { Следующие месяцы имеют по 30 дней: }
    4, 6, 9, 11:
       CountDay := 30;

    { Следующие месяцы имеют по 31 день: }
    1, 3, 5, 7, 8, 10, 12:
       CountDay := 31
  end;
  { Если D < CountDay, то увеличиваем день D на единицу;
  если D = CountDay, то следующий день равен 1, а месяц 
  увеличивается на 1 (первый день следующего месяца): }
  if D < CountDay then inc(D)
  else begin
    M := M mod 12 + 1;
    D := 1
  end;
  { ВЫВОДИМ РЕЗУЛЬТАТ: }  
  write('Следующая дата: ');
  if D < 10 then write('0', D, '.')
  else writeln(D, '.');
  if M < 10 then write('0', M)
  else writeln(M);
  readln
end.

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

* * *

Второе решение задачи Case9 предполагает проверку правильности введенных данных. Сначала вводим и проверяем данные (строки 8 – 27), находим количество дней CountDay для каждого месяца (строки 35 – 46), а потом определяем D и M в зависимости от CountDay (строки 50 – 54) и выводим результат (строки 56 – 60). В комментариях все пояснения.

var
  D, M, CountDay: byte;
  f: boolean;

begin
  { ВВОДИМ ДЕНЬ И МЕСЯЦ до тех пор, пока не 
  будет введена правильная дата: }
  repeat
    write('D = ');
    readln(D); { <-- Вводим день }
    write('M = ');
    readln(M); { <-- Вводим месяц }
    { Проверяем, является ли введенная дата правильной: }
    f := true; { <-- Считаем, что введенная дата правильная }
    case M of
      { Второй месяц имеет 28 дней: }
      2: if (D < 1) or (D > 28) then f := false;

      4,6,9,11: { <-- Месяцы имеют 30 дней }
         if (D < 1) or (D > 30) then f := false;

      1,3,5,7,8,10,12: { <-- Месяцы имеют 31 день }
         if (D < 1) or (D > 31) then f := false
      else f := false { <-- M<1 или M>12 }
    end;
    if f = false then writeln(' Такой даты не существует!')
  until f; { <-- Выходим, если введенная дата правильная }
  writeln;
  write('Вы ввели дату: ');
  if D < 10 then write('0', D, '.')
  else write(D, '.');
  if M < 10 then writeln('0', M)
  else writeln(M);
  { Группируем месяцы по количеству дней: }
  case M of
    { Второй месяц имеет всего 28 дней: }
    2: CountDay := 28;

    { Следующие месяцы имеют по 30 дней: }    
    4, 6, 9, 11:
       CountDay := 30;

    { Следующие месяцы имеют по 31 день: }    
    1, 3, 5, 7, 8, 10, 12:
       CountDay := 31
  end;
  { Если D < CountDay, то увеличиваем день D на единицу;
  если D = CountDay, то следующий день равен 1, а месяц 
  увеличивается на 1 (первый день следующего месяца): }
  if D < CountDay then inc(D)
  else begin
    M := M mod 12 + 1;
    D := 1
  end;
  { ВЫВОДИМ РЕЗУЛЬТАТ: }  
  write('Следующая дата: ');
  if D < 10 then write('0', D, '.')
  else writeln(D, '.');
  if M < 10 then write('0', M)
  else writeln(M);
  readln
end.

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

**type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255