Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 29.05.2011, 20:02
Row Row вне форума
Прохожий
 
Регистрация: 20.03.2011
Сообщения: 21
Репутация: 10
Вопрос Задачка на перечисляемый тип

Дано:
Код:
type месяц = ( янв, фев, мар, апр, май, июн, июл, авг, сен, окт, ноя, дек );
var k1:1..366; d:1..31; m:месяц;
Найти:
d, m - дату k-го по счету дня невисокосного года (о присвоенных значениях сообщить).

Задачку решил, используя case для вычислений, но беда в том, что использовать его можно только для вывода...
все вычисления должны происходить до него...

Не прошу решить полностью, хотя бы натолкните в какую сторону думать. Буду очень благодарен
Ответить с цитированием
  #2  
Старый 29.05.2011, 20:08
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Как я понял, это задачка из универовских/школьных? Какие же программисты оттуда выйдут...

Вопщем, создай константу-массив с количеством дней в месяцах. А дальше цикл while и
Код:
dec(k1,ЧИСЛО_ДНЕЙ_В_МЕСЯЦЕ[m]);
inc(m);
и подобные конструкции.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #3  
Старый 29.05.2011, 20:53
Row Row вне форума
Прохожий
 
Регистрация: 20.03.2011
Сообщения: 21
Репутация: 10
По умолчанию

Не в специалистах проблема.
Если бы мне можно было создать константу-массив, я бы ее создал или по-другому как-то решил.
В этом и проблема, что решить нужно стандартными способами (div, mod) или что-то в этом роде, ну циклы само-собой разумеется можно использовать... Вот такой у нас бзик.
Ответить с цитированием
  #4  
Старый 29.05.2011, 21:40
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Это и есть стандартный способ. Хотя бы в исходники Дельфи заглянул для интереса.
Код:
type
  PDayTable	= ^TDayTable;
  TDayTable	= array[1..12] of Word;

const
  MonthDays: array [Boolean] of TDayTable =
    ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
     (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));

function IsLeapYear(Year: Word): Boolean;
begin
  Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
end;

function DoEncodeDate(Year, Month, Day: Word; var Date: TDateTime): Boolean;
var
  I: Integer;
  DayTable: PDayTable;
begin
  Result := False;
  DayTable := @MonthDays[IsLeapYear(Year)];
  if (Year >= 1) and (Year <= 9999) and (Month >= 1) and (Month <= 12) and
    (Day >= 1) and (Day <= DayTable^[Month]) then
  begin
    for I := 1 to Month - 1 do Inc(Day, DayTable^[i]);
    I := Year - 1;
    Date := I * 365 + I div 4 - I div 100 + I div 400 + Day - DateDelta;
    Result := True;
  end;
end;

procedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word);
const
  D1 = 365;
  D4 = D1 * 4 + 1;
  D100 = D4 * 25 - 1;
  D400 = D100 * 4 + 1;
var
  Y, M, D, I: Word;
  T: Integer;
  DayTable: PDayTable;
begin
  T := DateTimeToTimeStamp(Date).Date;
  if T <= 0 then
  begin
    Year := 0;
    Month := 0;
    Day := 0;
  end else
  begin
    Dec(T);
    Y := 1;
    while T >= D400 do
    begin
      Dec(T, D400);
      Inc(Y, 400);
    end;
    DivMod(T, D100, I, D);
    if I = 4 then
    begin
      Dec(I);
      Inc(D, D100);
    end;
    Inc(Y, I * 100);
    DivMod(D, D4, I, D);
    Inc(Y, I * 4);
    DivMod(D, D1, I, D);
    if I = 4 then
    begin
      Dec(I);
      Inc(D, D1);
    end;
    Inc(Y, I);
    DayTable := @MonthDays[IsLeapYear(Y)];
    M := 1;
    while True do
    begin
      I := DayTable^[M];
      if D < I then Break;
      Dec(D, I);
      Inc(M);
    end;
    Year := Y;
    Month := M;
    Day := D + 1;
  end;
end;

Перебори свою лень.
Ответить с цитированием
  #5  
Старый 29.05.2011, 22:49
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Цитата:
Сообщение от Row
Если бы мне можно было создать константу-массив, я бы ее создал или по-другому как-то решил.
Иначе эта задача не решается. Либо константа-массив, либо case. Деление тут бесполезно, надеюсь ты понимаешь, почему. Либо разбирайся с преподами, либо делай по-хорошему (качественно, компактно) и защищай свой код как правильный (если он реально правильный).
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #6  
Старый 29.05.2011, 23:08
Row Row вне форума
Прохожий
 
Регистрация: 20.03.2011
Сообщения: 21
Репутация: 10
По умолчанию

Если бы это была лень, я бы не мучил людей на форуме.
Просто четко сказано: никаких функций, case только для вывода, по максимуму использовать перечисляемый тип и уж точно никаких массивов.
Ответить с цитированием
  #7  
Старый 29.05.2011, 23:11
Row Row вне форума
Прохожий
 
Регистрация: 20.03.2011
Сообщения: 21
Репутация: 10
По умолчанию

я то понимаю, что деление бесполезно.
Как писал выше, предлагаемые вами способы использовать нельзя.
вариант решения, с использование case делал, показывал, забраковали)
Ладно, пойду юзать, если долго мучиться, может и получится)
Ответить с цитированием
  #8  
Старый 29.05.2011, 23:12
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Я плюсану репутацию тому, кто кодом докажет, что возможно выполнить все эти условия.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #9  
Старый 30.05.2011, 00:03
Аватар для KOOL
KOOL KOOL вне форума
Активный
 
Регистрация: 06.01.2008
Адрес: Рязань
Сообщения: 306
Версия Delphi: 2009
Репутация: 6150
По умолчанию

1 января - 1-й день, значит, чтобы узнать дату k-го дня, надо прибавить к нему k-1 дней. Например, вот так:
Код:
procedure DateDaysSum(var D1:Date; Days:integer);
var buf:word;
begin
  if Days>0 then
    begin
      repeat
        if (D1.D+Days>29) and (D1.M=2) and (((D1.Y mod 100=0) and (D1.Y mod 400=0))or((D1.Y mod 4=0)and(D1.Y mod 100<>0)))then
          begin
            Days:=Days-(29-D1.D+1);
            D1.D:=1;
            D1.M:=D1.M+1;
          end
        else
          if (D1.D+Days>28) and (D1.M=2) and((D1.Y mod 4<>0)or((D1.Y mod 100=0)and(D1.Y mod 400<>0)))then
            begin
              Days:=Days-(28-D1.D+1);
              D1.D:=1;
              D1.M:=D1.M+1;
            end
          else
            if ((D1.D+Days>30) and (D1.M in [4, 6, 9, 11]))then
              begin
                Days:=Days-(30-D1.D+1);
                D1.D:=1;
               D1.M:=D1.M+1;
              end
            else
              if ((D1.D+Days>31) and (D1.M in [1, 3, 5, 7, 8, 10, 12]))then
                begin
                  Days:=Days-(31-D1.D+1);
                  D1.D:=1;
                  D1.M:=D1.M+1;
                end
              else
                begin
                  D1.D:=Days+1;
                  Days:=0;
                end;
        if D1.M>12 then
          begin
            buf:=(12-D1.M+1) mod 12 + 1;
            D1.M:=buf;
            D1.Y:=D1.Y+1;
          end;
      until Days<=0;
    end;
end;
Выдергиваем из процедуры. Если числовое значение года не нужно и он всегда невисокосный - убираем проверку на него. Никаких массивов и процедур(хотя с ними было бы гораздо проще). Ну и в Date и проверке месяца заменить на перечисляемые типы:
Код:
type месяц = ( янв=1, фев, мар, апр, май, июн, июл, авг, сен, окт, ноя, дек );
     Date=record
       Y: word;
       M: месяц;
       D: 1..31;
     end;
__________________
РГРТУ - ФВТ - Системы Автоматизированного ПРоектирования. ت
Ответить с цитированием
  #10  
Старый 30.05.2011, 01:17
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Row
Просто четко сказано...
Проще избавиться от такого препода как от не компетентного в программировании.
Ответить с цитированием
  #11  
Старый 30.05.2011, 01:34
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

"Компетентных в программировании" преподов не существует по двум причинам. Первая - если человек компетентен в программировании - он работает на хорошую компанию за хорошие деньги, и всякого рода учебные заведения ему нафиг не нужны. Вторая - у школ и ВУЗов есть определённая программа (и это не их вина, а МинОбр), которой обязаны придерживаться все преподы, хочется им этого или нет. Компетентный прогер на такой откровенный бред ни за что не согласится. Поэтому туда идут девочки с ПедФаков и им подобные, которые ни на что кроме как сидеть в "одноклассниках" неспособны. Оттого такое и получается...
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #12  
Старый 30.05.2011, 02:15
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

И это грустно.
Ответить с цитированием
  #13  
Старый 30.05.2011, 04:16
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

И, тем не менее, прекратили оффтоп.
%TS%, ты можешь проконсультироваться с преподом на тему "А что вообще можно использовать, и как Вы вообще это представляете"? Просто сейчас задача нерешаема при текущих условиях.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #14  
Старый 30.05.2011, 05:24
Row Row вне форума
Прохожий
 
Регистрация: 20.03.2011
Сообщения: 21
Репутация: 10
По умолчанию

консультировался я.
ответ был: "Я не знаю. Думайте. Думайте. Вы должны как-то формализировать, чтобы программа все высчитывала до case".
Все что мне можно использовать - это:
1) простейшие выражения
2) операторы ветвления
3) циклы
4) перечисляемый тип
Вот и все средства.
Ответить с цитированием
  #15  
Старый 30.05.2011, 08:17
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А все-таки, можно ли массив констант?

А то можно сделать как-то так:
Код:
const
  DaysInMonth : Array [1..12] Of Integer = 
    (31,28,31,30,31,30,31,31,30,31,31);
  Months : Array [1..12] Of String = 
    ('янв', 'фев', ...  ); // Ну вы поняли... это только для вывода

function GetDateByNumber(N : Integer)  : String;
var
  I, S : Integer;
begin
  Result := '';
  I := 1;
  S := 0;
  While S + DaysInMonth[i] < N Do
    Begin
      S := S + DaysInMonth[i];
      Inc(I);
      If I > 12 Then Raise Exception.Create('Over the year.');
    End;
  N := 
  Result := IntToStr(N - S) + ' ' + Months[i];
end;
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:26.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025