Решаю задание по записям, все вроде понятно, но есть один вопрос. Какой тип данных(и какой формат ДД.ММ.ГГ или еще как?) лучше использовать для нахождения минимальной(максимальной) даты?
sheka
21.01.2011 15:10
Если в делфях, то TDateTime. Если в паскале, то запись с полями Дата Месяц Год, а потом это все как-то переводить в дни, упрощенно(приближенно) можно так: Дата+30*(Месяц+12*Год). Но для этого конкретного задания нахождения минимальной(максимальной) даты, я лично бы использовал строки с форматом ГГГГ.ММ.ДД и проверял бы их на больше меньше. Это всегда даст однозначный ответ.
Добавлено через 11 мин. Извините, не внимательно прочитал задание Если использовать записи, то можно так
a: record Year: integer; Month: byte; Day: byte; end;
А потом если приближенно Дата+30*(Месяц+12*Год) не устраивает, делать кучу проверок на високосный/невисокосный год, на количество дней в месяце.
volvo
21.01.2011 16:43
Цитата
А потом если приближенно Дата+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.
- это уже очень сложно?
Евгений
21.01.2011 22:46
Цитата(volvo @ 21.01.2011 16:43)
- это уже очень сложно?
Для меня пока да, но попытаюсь разобраться. А почему нельзя тупо сначала сравнить года, если они равны. то месяцы и т.д?
sheka
21.01.2011 23:41
Эта фраза меня касалась
Можно. Тогда и получается "очень сложно".
Добавлено через 2 мин. Хотя эта функция и сравнивает дни, месяцы и годы, просто делает она это очень красиво.
volvo
22.01.2011 2:44
Цитата
Для меня пока да, но попытаюсь разобраться.
Что именно из приведенного кода вызывает сложность? Описание одной функции внутри другой?
Евгений
22.01.2011 6:37
Пока набросал вот это:
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.
Не очень красиво. но работает 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
22.01.2011 13:08
Цитата
{$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] - минимальная дата.
Евгений
22.01.2011 22:30
Даа.. В вычислениях логических выражений у меня пробел, будем восстанавливать...
Цитата
Разницы вообще не вижу:
Теперь я тоже . Видимо сказывается ночная работа(ну надо же как то оправдаться ). Спасибо!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.