реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Алгоритм нахождения праздничной даты.
Jenya7
сообщение Feb 1 2015, 07:38
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Есть RTC.
Код
struct sRTC
{
    uint8_t rtcYear;
    uint8_t rtcMonth;
    uint8_t rtcDay;
    uint8_t rtcDayOfWeek;
    uint8_t rtcHour;
    uint8_t rtcMin;
    uint8_t rtcSec;

};

extern struct sRTC rtc;

Инициализирую
Код
rtc.rtcYear = 2015;
rtc.rtcMonth = 1;
rtc.rtcDay = 29;
rtc.rtcDayOfWeek = 5;
rtc.rtcHour = 12;
rtc.rtcMin = 30;
rtc.rtcSec = 10;


Нужно послать сигнал когда праздник подошел . Скажем 9 Мая. Как это сделать? Думал забить таблицу праздников на 20 лет вперед и каждый час сравнивать текущую дату но подозреваю это не самое лучшее решение.
Go to the top of the page
 
+Quote Post
gerber
сообщение Feb 1 2015, 08:50
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Можно отслеживать изменение дня, и в момент изменения дня анализировать праздничную таблицу, один раз в сутки.
Код
static uint8_t nPrevDay = 255;
if(rtc.rtcDay != nPrevDay)
{
  nPrevDay = rtc.rtcDay;

  if( (rtc.rtcDay == 13) && (rtc.rtcDayOfWeek == 5) )
  {
    printf("Пятница 13-е !!!\r\n");
  }
}


Сообщение отредактировал gerber - Feb 1 2015, 10:03


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 1 2015, 09:05
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



если пойти прямым путем то раз в сутки мне нужно перебрать все праздничные даты и сравнить с моей, так я знаю наступила праздничная дата или нет. а что если так. взять первый праздник в году и от него отсчитывать дни. при старте системы посчитать где наша дата по отношению к первому празднику.
и потом обрабатывать случаи. скажем прошло сто дней - значит второй праздник, 150 дней - третий праздник и.т.д.
Go to the top of the page
 
+Quote Post
fider
сообщение Feb 1 2015, 09:07
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 174
Регистрация: 28-08-07
Из: Сибирь
Пользователь №: 30 115



Видимо можно и так, только с учетом високосного года.
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Feb 1 2015, 10:33
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(Jenya7 @ Feb 1 2015, 09:05) *
если пойти прямым путем то раз в сутки мне нужно перебрать все праздничные даты и сравнить с моей, так я знаю наступила праздничная дата или нет. а что если так. взять первый праздник в году и от него отсчитывать дни. при старте системы посчитать где наша дата по отношению к первому празднику.
и потом обрабатывать случаи. скажем прошло сто дней - значит второй праздник, 150 дней - третий праздник и.т.д.


There are many ways to skin a cat. Можно, например, завести битовый массив длинной 365 бит sm.gif Если единичка установлена, то в соотв. день - просто праздник какой-то!
Получается типа однобитной хэш-таблицы. Некоторая проблема возникнет, если на один день приходится несколько праздников.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 1 2015, 11:15
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(CrimsonPig @ Feb 1 2015, 16:33) *
There are many ways to skin a cat. Можно, например, завести битовый массив длинной 365 бит sm.gif Если единичка установлена, то в соотв. день - просто праздник какой-то!
Получается типа однобитной хэш-таблицы. Некоторая проблема возникнет, если на один день приходится несколько праздников.

мне кажется что работа с таким массивом не отличается от перебора. мне нужна оптимизация по скорости.
Go to the top of the page
 
+Quote Post
CrimsonPig
сообщение Feb 1 2015, 11:23
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502



Цитата(Jenya7 @ Feb 1 2015, 11:15) *
мне кажется что работа с таким массивом не отличается от перебора. мне нужна оптимизация по скорости.


Не понял.. ваши часы не знают, какой по счету день года сегодня ?
Заведите тогда еще и счетчик дней с 1 Января.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Feb 1 2015, 11:26
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(Jenya7 @ Feb 1 2015, 14:15) *
мне нужна оптимизация по скорости.

праздников не так много, массив небольшой с номерами дней.
поиск сделать по бинарному дереву
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Feb 2 2015, 04:35
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



А что если все праздники отсортировать и в момент перехода на новый день сравнивать только с одной датой - самой ближайшей. При наступлении этой даты - взводить счетчик на следующую ближайшую дату. Ну и раз в полгода добавлять в отсортированную таблицу следующие даты. И никаких переборов.
Go to the top of the page
 
+Quote Post
nill
сообщение Feb 2 2015, 06:11
Сообщение #10


Частый гость
**

Группа: Validating
Сообщений: 124
Регистрация: 10-08-05
Пользователь №: 7 502



На эти грабли уже наступали? Или это просто пример с потолка?
Цитата(Jenya7 @ Feb 1 2015, 14:38) *
Код
struct sRTC
{
    uint8_t rtcYear;
};

Код
rtc.rtcYear = 2015;

Go to the top of the page
 
+Quote Post
Grizzzly
сообщение Feb 2 2015, 08:23
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 565
Регистрация: 22-02-13
Пользователь №: 75 748



Цитата(alexeyv @ Feb 2 2015, 07:35) *
И никаких переборов.

Не понял, откуда берутся переборы?
Не проще ли создать массив uint32_t holidays[12], в котором, как предложил CrimsonPig, будут отмечены единичными битами праздники. В данном случае даже счетчик числа дней от начала года не нужен. По rtcMonth выбираем месяц из массива, по rtcDay выделяем нужный бит и проверяем его на равенство единице.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 2 2015, 08:36
Сообщение #12


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Grizzzly @ Feb 2 2015, 14:23) *
Не понял, откуда берутся переборы?
Не проще ли создать массив uint32_t holidays[12], в котором, как предложил CrimsonPig, будут отмечены единичными битами праздники. В данном случае даже счетчик числа дней от начала года не нужен. По rtcMonth выбираем месяц из массива, по rtcDay выделяем нужный бит и проверяем его на равенство единице.

а почему 12 элементов? тогда нужен второй вектор - дни в месяце.

Цитата(nill @ Feb 2 2015, 12:11) *
На эти грабли уже наступали? Или это просто пример с потолка?

я потом делаю +/- 2000
Go to the top of the page
 
+Quote Post
Grizzzly
сообщение Feb 2 2015, 08:42
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 565
Регистрация: 22-02-13
Пользователь №: 75 748



Цитата(Jenya7 @ Feb 2 2015, 11:36) *
а почему 12 элементов? тогда нужен второй вектор - дни в месяце.

По числу месяцев. В месяце не может быть больше 31 дня. Поэтому 32 бит в каждом элементе массива вам хватит. Дальше битовыми сдвигами добираетесь до нужного дня.
Go to the top of the page
 
+Quote Post
adnega
сообщение Feb 2 2015, 09:13
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Праздники не наступают каждые 10 мс.
Поэтому если есть ограничение по скорости, то нужно процесс вычисления даты разбить на множество шагов.
Например, за один шаг фоном проверять одну дату из массива хоть перебором.
К моменту вызова функции сегодня_праздник() подготовить и выдать мгновенно ответ не составит труда.
Go to the top of the page
 
+Quote Post
WitFed
сообщение Feb 2 2015, 13:34
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 271
Регистрация: 6-12-11
Из: Taganrog
Пользователь №: 68 701



Мне кажется, что предложение alexeyv было самым сбалансированным, только недожёванным.
Иметь массив из 10-40 (с Днями Пограничника) пар чисел: (месяц, день) не займёт много памяти, ну и переменную i -- позицию, которую мы ждём. А сравнить с текущими 2 полями структуры времени, когда захочется -- недолго. Совпало -- пискнули наружу, инкрементировали i и обнулили её, если "заступ" за границу массива -- и опять ждём... Больше одного раза на совпадение такая схема не сработает -- сразу же начинается ожидание следующего праздника. И праздников не один, чтобы циклить по одному месту. От объёма "праздности" код не зависит.
Вроде ж праздники у нас от года к году не прыгают, чтобы хранить их на 10 лет вперёд ? Ну только если что-то добавится/убавится Думой официально -- так это любую софтину придётся корректировать.
P.S. Единственный минус -- нужно задать правильное значение i при пуске системы, просчитать позицию умозрительно, а то первый "писк" может быть только через год wink.gif
Т.е. для "совсем мозговитости" этого куска программы можно сравнивать текущее время не только с "[i]"-й позицией, но и "[i-1]"-й, и если "не туда попали" стартовой настройкой, то сдвигать её вперёд. Через несколько временных интервалов проверки система придёт в нормальное состояние.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 15:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01479 секунд с 7
ELECTRONIX ©2004-2016