Это должно быть довольно легко сделать. Учтите, что DayOfWeek.Sunday == 0
, Monday == 1
и т. Д.
Ваша маска соответствует этому. То есть в вашей маске:
Sunday = 1 << 0
Monday = 1 << 1
Tuesday = 1 << 2
Теперь, учитывая день недели, мы можем легко определить день, который будет соответствовать вашим критериям:
[Flags]
enum DayMask
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
static DayOfWeek FindNextDay(DayMask mask, DayOfWeek currentDay)
{
DayOfWeek bestDay = currentDay;
int bmask = 1;
for (int checkDay = 0; checkDay < 7; ++checkDay)
{
if (((int)mask & bmask) != 0)
{
if (checkDay >= (int)currentDay)
{
bestDay = (DayOfWeek)checkDay;
break;
}
else if (bestDay == currentDay)
{
bestDay = (DayOfWeek)checkDay;
}
}
bmask <<= 1;
}
return bestDay;
}
Например, днем, который вы хотите сопоставить, является среда, но маска содержит только понедельник. Вы можете видеть, что алгоритм выберет понедельник как лучший день, а затем пройдет остаток дней, ничего не выбирая.
Если маска содержит понедельник, вторник и четверг, алгоритм выберет понедельник в качестве лучшего кандидата, проигнорирует вторник, а затем выберет четверг в качестве лучшего кандидата и выйдет.
Это будет не так быстро, как справочная таблица, но должно быть чертовски быстро. И он будет использовать намного меньше памяти, чем справочная таблица.
Таблица поиска была бы намного быстрее, и это не заняло бы, кроме килобайта памяти. А учитывая метод FindNextDay
, описанный выше, достаточно просто построить:
static byte[,] LookupTable = new byte[128, 7];
static void BuildLookupTable()
{
for (int i = 0; i < 128; ++i)
{
DayMask mask = (DayMask)i;
for (int day = 0; day < 7; ++day)
{
LookupTable[i, day] = (byte)FindNextDay(mask, (DayOfWeek)day);
}
}
}
Теперь, чтобы получить следующий день для любой комбинации маски и текущего дня:
DayOfWeek nextDay = (DayOfWeek)LookupTable[(int)mask, (int)currentDay];
Несомненно, есть более быстрый способ создания таблицы. Но это достаточно быстро, и, поскольку он будет выполняться один раз при запуске программы, нет особой смысла его оптимизировать. Если вы хотите, чтобы запуск происходил быстрее, напишите небольшую программу, которая выведет таблицу в виде кода на C #. Что-то вроде:
Console.WriteLine("static byte[,] LookupTable = new byte[128,7] {");
for (int i = 0; i < 128; ++i)
{
Console.Write(" {");
for (int j = 0; j < 7; ++j)
{
if (j > 0)
{
Console.Write(",");
}
Console.Write(" {0}", LookupTable[i, j]);
}
Console.WriteLine(" },");
}
Console.WriteLine("};");
Затем вы можете скопировать и вставить это в вашу программу.