Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Алгоритм календаря


Автор: Politexnik 5.3.2008, 17:36
Здравствуйте!!!

Когда смотришь на наш календарь, невольно приходит мысль о том, что есть некий алгоритм его построения. Ведь дни недели данного месяца каждый год двигаются на один день вперед.
После високосных годов передвигаются аж на два дня, и т.д. Попытался как-то всунуть это в концепцию С++, но не очень то получилось. Буду рад, если ВЫ мне подскажите, как это реализовать.
Это НЕ вопрос "жизни и смерти" (как любят многие говорить).
Просто ради интереса.

Заранее благодарен!

Автор: JackYF 5.3.2008, 17:59
Цитата(Politexnik @  5.3.2008,  16:36 Найти цитируемый пост)
ак это реализовать.

что реализовать? в чём проблема?

Автор: Politexnik 5.3.2008, 18:30
Дорогой  JackYF
Проблема в самом построении алгоритма!
К примеру то же передвижение дня недели изо года в год.
Можно сунуть в цикл???
Можно!!!
Только как сделать так, чтоб через каждые 4 года день перепрыгивал на два шага вперед???
Или дни месяца...
Как сделать чередование месяцев с 30 и 31 днями(ведь в чередующихся июле и августе по 31 дню в каждом). Не говорю про февраль со своими 28 днями и этим
високосным днем. 
Саму схему построения и вывода месяца можно сделать матрицей.
Это понятно.
А как же остальное???

Автор: bsa 5.3.2008, 20:12
воспользуйся функцией localtime и будет тебе счастье.

Автор: Politexnik 5.3.2008, 21:07
Цитата

воспользуйся функцией localtime и будет тебе счастье.



Можно немножечко поподробнее???

Автор: bsa 5.3.2008, 21:26
Цитата(Politexnik @ 5.3.2008,  21:07)
Можно немножечко поподробнее???

http://www.google.com/search?q=man+localtime -> http://linux.die.net/man/3/localtime

Автор: Politexnik 5.3.2008, 23:08
Спасибо,  bsa.
Но неужели это значит, что НЕЛЬЗЯ на С++ написать алгоритм календаря??? smile 
Цитата

и будет тебе счастье.

Счастье будет когда я САМ (или с Вашей помощью) напишу алгоритм календаря smile 

Автор: bsa 5.3.2008, 23:35
http://www.cs.umd.edu/~khennacy/research/cell/calendar.pdf

Алгоритмы не пишутся на Си/Си++ или других языках. Алгоритмы пишутся на псевдоязыках. И если у тебя вопрос по алгоритмам, то тебе в другой раздел.

Автор: andfurs 6.3.2008, 00:21
 попробуй в вики набрать ВЕЧНЫЙ КАЛЕНДАРЬ, там будут таблицы по которой можно вычислить дни недели в районе 2500 лет.

Автор: Dmi3ev 6.3.2008, 11:37
алгоритм примерно такой, берешь один день, в котором ты точно уверен, например 6.03.08 - четверг. затем допустим тебе надо определить что за день недели 13.03.08 для этого тебе нужно разность дат разделить на 7 (кол-во дней недели). если остаток от деления 0, значит -четверг, если 6 -среда, если 5 - вторник и т.д. а каждый четвертый раз добавлять дату 29 февраля. если же ты и даты не хочешь использовать, а все хочешь написать сам, то можно и другое предложить)

Добавлено через 58 секунд
забыл написать что разность дат нужно делить на 7)))) извини

Автор: bsa 6.3.2008, 11:46
Dmi3ev, а то что год делящийся нацело на 100 високосным не является, а те что делятся на 1000 являются ты учел?

Автор: virtual09 6.3.2008, 11:59
Цитата(bsa @  6.3.2008,  11:46 Найти цитируемый пост)
а то что год делящийся нацело на 100 високосным не является

а что разве 2000, или 1900 не являются високосными ?

Автор: Dmi3ev 6.3.2008, 12:08
я про год ничего не говорил, кроме того, что сейчас он високосный и мы это знаем, каждые 4 года он високосный, тоже знаем, соответственно можно в цикле сделать условие, что каждый 4 раз 29 февраля будет. просто не совсем понятно, что именно человек хочет. ведь можно тупо пользоваться функциями С++ или установить билдер и кинутьDateTimePicker на форму))))))))))))

Добавлено через 2 минуты и 46 секунд
bsa, действительно, 1900 и 2000 не високосные????? я про это ничего не знаю и virtual09 тоже, поясни????

Автор: bsa 6.3.2008, 12:44
Цитата(virtual09 @ 6.3.2008,  11:59)
Цитата(bsa @  6.3.2008,  11:46 Найти цитируемый пост)
а то что год делящийся нацело на 100 високосным не является

а что разве 2000, или 1900 не являются високосными ?

1900 не является (делится на 100). 2000 является (делится на 400, я ошибся когда сказал 1000): http://ru.wikipedia.org/wiki/Високосный_год

Автор: Dmi3ev 6.3.2008, 12:55
спасибо, к своему стыду не знал, честно признаюсь. bsa, спасибо!!! значит надо добавить и эти условия с делением года 100 и 400, и задача решится.
bsa, ещё раз спасибо, никак не думал (может, потому что не жил в 1900)))))))

Автор: engaged 5.2.2013, 12:32
bsa
а как определить, например, что 2012 был високосным? На 400 без остатка-то он не делится.

upd: Ой, это я спустя 5 лет спросил  smile 

Автор: borisbn 5.2.2013, 14:36
engaged, ничего страшного. главное, чтобы не через 400  smile 
Цитата(engaged @  5.2.2013,  12:32 Найти цитируемый пост)
как определить, например, что 2012 был високосным?

делится на 4, не делится на 100 (а раз он на 100 не делится, то вопрос о том, делится ли он на 400 отпадает сам собой. ещё раз  smile  )

Автор: feodorv 5.2.2013, 16:46
Цитата(borisbn @  5.2.2013,  15:36 Найти цитируемый пост)
то вопрос о том, делится ли он на 400 отпадает сам собой

Это не совсем так:
Код

#define isLeapYear(y) \
    (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

То есть 1500, 1700, 1800, 1900, 2100 - не високосные года.
1600, 2000, 2400 - високосные.

Автор: borisbn 5.2.2013, 17:25
feodorv, эк Вы умело процитировали  smile 
не
Цитата(borisbn @  5.2.2013,  14:36 Найти цитируемый пост)
то вопрос о том, делится ли он на 400 отпадает сам собой

а
Цитата(borisbn @  5.2.2013,  14:36 Найти цитируемый пост)
а раз он на 100 не делится, то вопрос о том, делится ли он на 400 отпадает сам собой


Автор: feodorv 5.2.2013, 17:41
Цитата(borisbn @  5.2.2013,  18:25 Найти цитируемый пост)
feodorv, эк Вы умело процитировали  

Мда, прошу прощения smile 

Автор: volatile 5.2.2013, 18:03
Цитата(engaged @  5.2.2013,  12:32 Найти цитируемый пост)
как определить, например, что 2012 был високосным?

вибирайте:
Код

// Только для нового стиля
int is_leap_year_0 (int year)
{
   if (year %   4) return 0;
   if (year % 100) return 1;
   if (year % 400) return 0;
   return 1;
}

//--------------------------------
// Только для нового стиля
int is_leap_year_1 (int year)
{
    return ((year % 4 == 0 && year % 100) || year % 400 == 0);
}

//--------------------------------
// Только для нового стиля
int is_leap_year_2 (int year)
{
   return (year % 400 == 0 || (year % 100 && year % 4 == 0));
}

//--------------------------------
// Для нового и старого стилей
int is_leap_year_3 (int year, bool style)
{
   int q = year % 4 == 0;
   if (!q || style)
      return q;
   return year % 400 == 0 || year % 100 != 0;
}

//--------------------------------
// Для нового и старого стилей
int is_leap_year_4 (int year, bool style)
{
   if (year %   4) return 0;
   if ( style ) return 1;
   if (year % 100) return 1;
   if (year % 400) return 0;
   return 1;
}

//--------------------------------
// Для нового и старого стилей
int is_leap_year_5 (int year, bool style)
{
   int res = year % 4 == 0;
   if (!res) ;
   else if (style) ;
   else if (year % 100) ;
   else if (year % 400) res = 0;
   return res;
}

//--------------------------------
// Для нового и старого стилей
int is_leap_year_6 (int year, bool style)
{
   int res = year % 4 == 0;
   if (res)
      if (!style)
         if (year % 100 == 0)
            if (year % 400) res = 0;
   return res;
}
//--------------------------------
// Для нового и старого стилей
int is_leap_year_7 (int year, bool style)
{
   int res = year % 4 == 0;
   if (res && !style && year % 100 == 0 && year % 400)
      res = 0;
   return res;
}
//--------------------------------
// Для нового и старого стилей
int is_leap_year_8 (int year, bool style)
{
   int res = !(year % 4);
   return res && !style && !(year % 100) && year % 400 ? 0 : res;
}

//--------------------------------
// с использованием сторонней функции.
int is_leap_year_9 (int year, bool style)
{
   return serial_day (1, 3, year, style) - serial_day (29, 2, year, style);
}



Автор: borisbn 5.2.2013, 22:05
Цитата(volatile @  5.2.2013,  18:03 Найти цитируемый пост)
  if (year % 100) return 1;
   if (year % 400) return 0;


Неа.

Добавлено @ 22:14
Цитата(borisbn @  5.2.2013,  22:05 Найти цитируемый пост)
Неа. 

хотя, нет.
Ага.
это я уже начал брать в привычку (привет Java), что под if'ом должно быть только Boolean, и такого рода выражения читаются уже немного по-другому. Жаль что в плюсиках это - нормально.

Автор: volatile 5.2.2013, 23:17
Цитата(borisbn @  5.2.2013,  22:05 Найти цитируемый пост)
такого рода выражения читаются уже немного по-другому

имхо, нормально читаюцца.
А жаба нам не указ, она, по последним сведениям,  ваще от паскаля произошла   smile

Автор: volatile 6.2.2013, 00:02
Ладно, еще немного в тему, кину кость любителям поиздевацца над синтаксисом С/С++ smile
(врочем так действитеьно писать не надо.)

Получение дня недели.
Универсальная, для нового и старого стилей.
вход: d, m, y - день, месяц, год
      s - стиль. 1- новый стиль (gregorian), 0 - старый стиль (julian). 
      (наоборот по сравнению с вышеприведенными високосами!)
(диапазон годы: [1.9999])
выход: 0=Вск, 1=Пон, ... 6=Суб
Код

int day_of_week (int d, int m, int y, bool s)

   d+=m<3?3+--y:y;return(d+y/4+s*(y/400-y/100+2)+23*m/9)%7; 
}

Автор: feodorv 6.2.2013, 08:40
Цитата(volatile @  6.2.2013,  01:02 Найти цитируемый пост)
Универсальная, для нового и старого стилей.

Забавная штука. Проверил на всём диапазоне time_t - работает smile 

Автор: borisbn 6.2.2013, 08:48
Цитата(volatile @  6.2.2013,  00:02 Найти цитируемый пост)
Универсальная, для нового и старого стилей.

день должен задаваться от 0 ? Если нет, то неправильно работает - http://liveworkspace.org/code/17VwPR$4

Автор: feodorv 6.2.2013, 08:56
Цитата(borisbn @  6.2.2013,  09:48 Найти цитируемый пост)
то неправильно работает

А чем Вас среда не устраивает?
Цитата(volatile @  6.2.2013,  01:02 Найти цитируемый пост)
выход: 0=Вск, 1=Пон, ... 6=Суб


Автор: borisbn 6.2.2013, 13:06
Цитата(feodorv @  6.2.2013,  08:56 Найти цитируемый пост)
А чем Вас среда не устраивает?
Цитата(volatile @  6.2.2013,  01:02 )
выход: 0=Вск, 1=Пон, ... 6=Суб


блин.. опять невнимательно прочитал. всё-таки американская система исчисления дней недели (от Вск.) непривычная..

Автор: feodorv 6.2.2013, 13:18
Да ладно, 1:1 smile 

Автор: NoviceF 8.2.2013, 12:56
Цитата(volatile @  6.2.2013,  00:17 Найти цитируемый пост)
А жаба нам не указ, она, по последним сведениям,  ваще от паскаля произошла    

 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)