这应该很容易做到。考虑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("};");
然后您可以将其复制并粘贴到您的程序中。