Помощь - Поиск - Пользователи - Календарь
Полная версия: Тип данных для сравнения даты
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Евгений
Решаю задание по записям, все вроде понятно, но есть один вопрос. Какой тип данных(и какой формат ДД.ММ.ГГ или еще как?) лучше использовать для нахождения минимальной(максимальной) даты?
sheka
Если в делфях, то TDateTime.
Если в паскале, то запись с полями Дата Месяц Год, а потом это все как-то переводить в дни, упрощенно(приближенно) можно так: Дата+30*(Месяц+12*Год).
Но для этого конкретного задания нахождения минимальной(максимальной) даты, я лично бы использовал строки с форматом ГГГГ.ММ.ДД и проверял бы их на больше меньше. Это всегда даст однозначный ответ.


Добавлено через 11 мин.
Извините, не внимательно прочитал заданиеsmile.gif
Если использовать записи, то можно так
a: record
Year: integer;
Month: byte;
Day: byte;
end;

А потом если приближенно Дата+30*(Месяц+12*Год) не устраивает, делать кучу проверок на високосный/невисокосный год, на количество дней в месяце.

volvo
Цитата
А потом если приближенно Дата+30*(Месяц+12*Год) не устраивает, делать кучу проверок на високосный/невисокосный год, на количество дней в месяце.
А если написать функцию сравнения, которая будет возвращать (+1) когда First > Second, 0 если даты равны, и (-1) если First < Second:

type
RData = record
Day, Month, Year : Integer;
end;

{$B-}
function Compare (First, Second : RData) : Integer;

function Impl (var R : Integer; A, B : Integer) : Boolean;
begin
Impl := True;
R := A - B;

if R <> 0 then R := R div Abs( R ) else Impl := False;
end;

var
Res : Integer;
begin
if not Impl (Res, First.Year, Second.Year) and
not Impl (Res, First.Month, Second.Month) and
not Impl (Res, First.Day, Second.Day) then Res := 0;

Compare := Res;
end;

const
F : RData = (Day : 11; Month : 01; Year : 2011);
S : RData = (Day : 12; Month : 11; Year : 2010);
begin
writeln (Compare (F, S))
end.

- это уже очень сложно?
Евгений
Цитата(volvo @ 21.01.2011 16:43) *


- это уже очень сложно?

Для меня пока да, но попытаюсь разобраться.
А почему нельзя тупо сначала сравнить года, если они равны. то месяцы и т.д?
sheka
Эта фраза меня касалась smile.gif

Можно. Тогда и получается "очень сложно".


Добавлено через 2 мин.
Хотя эта функция и сравнивает дни, месяцы и годы, просто делает она это очень красиво.
volvo
Цитата
Для меня пока да, но попытаюсь разобраться.
Что именно из приведенного кода вызывает сложность? Описание одной функции внутри другой?
Евгений
Пока набросал вот это:
program data;
type data_r= record;
god: integer;
mes: 1..12;
chislo: 1..31;
end;

Var
dat: array [1..3] of data_r;
Mindata: byte;
i: byte;

begin
for i:= 1 to 3 do
with dat [i] do

begin
writeln('введите год ');
readln(god);
writeln('введите месяц(1..12) ');
readln(mes);
writeln('введите число(1..31) ');
readln(chislo);
end;
Mindata:=1;
for i:= 2 to 3 do
begin

if dat[i].god < dat[mindata].god then
Mindata:= i
else
if dat[i].mes < dat[mindata].mes then
Mindata:= i
else
if dat[i].chislo < dat[mindata].chislo then
Mindata:= i;
end;
writeln('минимальная дата ',dat[Mindata].god,'.',dat[mindata].mes,'.',dat[Mindata].chislo);
readln;

end.


Не очень красиво. но работает smile.gif
volvo по вашему решению есть несколько вопросов:
type
RData = record
Day, Month, Year : Integer;
end;

{$B-}//что это?//
function Compare (First, Second : RData) : Integer;//описание функций понятно//

function Impl (var R : Integer; A, B : Integer) : Boolean;
begin
Impl := True;
R := A - B;

if R <> 0 then R := R div Abs( R ) else Impl := False;
end;

var
Res : Integer;
begin
if not Impl (Res, First.Year, Second.Year) and
not Impl (Res, First.Month, Second.Month) and
not Impl (Res, First.Day, Second.Day) then Res := 0;//здесь как я понимаю, если все функции не фальш,т.е Res=0, то результат =0 ? //

Compare := Res;//а вот здесь не пойму, почему результат равен 1? Получается в превой функции Res=1, а во второй и третьей -1?//
end;

const
F : RData = (Day : 11; Month : 01; Year : 2011);
S : RData = (Day : 12; Month : 11; Year : 2010);
begin
writeln (Compare (F, S))
end.

Вы меня извините возможно за глупые вопросы.
P.S: Интересно а как все это реализовать если дат будет например 10 или больше?

volvo
Цитата
{$B-}//что это?//
Это гарантия включенной "короткой схемы" вычисления логических выражений. Что такой "короткая схема", знаешь? Это - когда логическое выражение вычисляется до тех пор, пока не станет очевидным результат. Теперь, смотри что происходит.



if
// сначала сравниваем годы. Если они разные - то результат
// Impl уже будет равным True, соответственно not True = False...
// Дальше в выражении только And-ы, что бы следующие Impl-ы
// ни вернули, результат все равно уже False, поэтому здесь выполнение
// прекратится, и уйдем на Compare := Res
not Impl (Res, First.Year, Second.Year) and

// Ага. Мы пришли сюда... Значит, годы одинаковые, предыдущий Impl
// вернул False, соответственно not Imple = True, и результат общего
// логического выражения зависит от следующих его частей. Продолжаем
// по тому же алгоритму, сравниваем месяцы...
not Impl (Res, First.Month, Second.Month) and
not Impl (Res, First.Day, Second.Day) then Res := 0;

// В итоге, если годы, месяцы, и дни - одинаковые, то общее выражение - Истина,
// в переменную Res заносится 0, и потом этот 0 возвращается как результат
// функции.

// А вот если ходя бы одно из полей (неважно какое, год это, месяц, или день)
// не совпадет - то вычисление тут же прервется, в переменной Res останется то,
// что было на момент выхода из Impl, обнуляться Res не будет, и функция вернет
// (+1) или (-1), смотря, какая дата больше



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

Цитата
   function Impl (var R : Integer; A, B : Integer) : Boolean;
begin
Write('*'); { <--- Вот сюда }
Impl := True;
R := A - B;
if R <> 0 then R := R div Abs( R ) else Impl := False;
end;
, и поиграйся с входными датами. Если они будут разных годов - то напечатается одна звездочка и потом (+/-)1, то есть, Impl выполнялась только один раз, сравнились только года, потом выполнение Compare закончилось. Если годы одинаковые, а разные - месяцы, то напечатается 2 звездочки и результат, иначе - все три звездочки...

Цитата
P.S: Интересно а как все это реализовать если дат будет например 10 или больше?
Интересно, а если у тебя есть массив из 10 целых чисел (или больше), как ты в нем находишь минимум? Может, сравниваешь каждое число с текущим минимумом, и если оно еще меньше - то запоминаешь новый индекс? Чем даты хуже? Функция сравнения у тебя есть. Разницы вообще не вижу:
IndexMin := 1;
for i := 2 to array_size do
if Compare(dat[indexMin], dat[ i ]) < 0 then IndexMin := i;

Вот и все, в результате dat[IndexMin] - минимальная дата.
Евгений
Даа.. В вычислениях логических выражений у меня пробел, будем восстанавливать...
Цитата
Разницы вообще не вижу:

Теперь я тоже smile.gif . Видимо сказывается ночная работа(ну надо же как то оправдаться smile.gif ). Спасибо!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.