从一组闹钟中获取第一个闹钟时间
Getting the first alarm time from set of alarms
我目前正在研究具有多个(重复发生的)闹钟的闹钟。
我正在使用 raspberry pi 安装了 Microsoft IoT 和 UWP (C#) 的布局和底层算法。
我 运行 遇到的问题是检索下一个闹钟时间。
伪代码:
Select nextAlarm()
For all alarms a
if (((a.time >= now.time AND a.repeatDay == now.DayOfWeek)
OR a.repeatDay > now.DayOfWeek) AND a.dateTime < currentAlarm.dateTime)
currentAlarm = a;
然而,这将花费 O(n) 的时间来处理每个警报,并且函数 a.repeatDay > now.DayOfWeek 不是一个简单的函数(如果当天是星期三并且下一个警报打开星期一,该功能不起作用)。
我要问的是如何以上述功能起作用的方式存储警报(并且最好比 O(n) 更快)或者我如何存储所述问题已解决的重复天数。
目前正在使用 SQLite.net-pcl 套餐
闹钟和 RepeatDay class:
public class Alarm
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
[NotNull]
public string Name { get; set; }
[NotNull]
public DateTime Time { get; set; }
[NotNull]
public int Repeat { get; set; }
public Alarm(string name, DateTime time, RepeatWeek repeat)
{
this.Name = name;
this.Time = time;
this.Repeat = repeat;
}
}
public class RepeatWeek
{
int repeat = 0;
public static implicit operator int(RepeatWeek w)
{
return w.repeat;
}
public void setDay(DayOfWeek w)
{
repeat |= 1 << (int)w;
}
public void removeDay(DayOfWeek w)
{
repeat &= ~(1 << (int)w);
}
public DayOfWeek getNext(DayOfWeek d, bool inclToday = false)
{
throw new NotImplementedException();
return DayOfWeek.Monday; //Needs work
}
}
我已经尝试实现 GetNextDay。然后实现 Alarm.GetNext 就变得很简单,一个更简单的 LINQ 查询就可以满足您的要求。我留了一些给你去实现,这样你就可以说你做到了。
public class Alarm
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime Time { get; set; }
public int Repeat { get; set; }
public Alarm(string name, DateTime time, RepeatWeek repeat)
{
this.Name = name;
this.Time = time;
this.Repeat = repeat;
}
public DateTime GetNext()
{
var includeToday = true;
if (DateTime.Now.TimeOfDay > Time.TimeOfDay)
{
includeToday = false;
}
var repeat = new RepeatWeek(Repeat);
var nextDayOfWeek = repeat.GetNextDay(includeToday);
return MergeDayOfWeekAndTime(nextDayOfWeek, Time);
}
private DateTime MergeDayOfWeekAndTime(DayOfWeek? nextDayOfWeek, DateTime Time)
{
//Left as exercise to the reader.
throw new NotImplementedException();
}
}
public class RepeatWeek
{
int Repeat;
public RepeatWeek(int repeat = 0)
{
Repeat = repeat;
}
public static implicit operator int(RepeatWeek w)
{
return w.Repeat;
}
public void setDay(DayOfWeek w)
{
Repeat |= 1 << (int)w;
}
public void removeDay(DayOfWeek w)
{
Repeat &= ~(1 << (int)w);
}
public static DayOfWeek FollowingDayOfWeek(DayOfWeek day)
{
if (day == DayOfWeek.Saturday)
{
return DayOfWeek.Sunday;
}
else
{
return day + 1;
}
}
public DayOfWeek? GetNextDay(bool inclToday = false)
{
var inspect = DateTime.Now.DayOfWeek;
if (!inclToday)
{
inspect = FollowingDayOfWeek(inspect);
}
for (int i = 0; i < 7; i++)
{
if ((Repeat & (1 << (int)inspect)) > 0) return inspect;
inspect = FollowingDayOfWeek(inspect);
}
return null;
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public void GetNextDayOfWeek()
{
var repeat = new RepeatWeek();
repeat.setDay(DayOfWeek.Monday);
repeat.setDay(DayOfWeek.Tuesday);
var expected = DayOfWeek.Monday;
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
{
expected = DayOfWeek.Tuesday;
}
var actual = repeat.GetNextDay();
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void GetNextAlarm()
{
//Populate this yourself.
var alarms = new List<Alarm>();
var nextAlarm = alarms.Select(a => a.GetNext()).OrderBy(a => a.Ticks).FirstOrDefault();
}
}
我目前正在研究具有多个(重复发生的)闹钟的闹钟。
我正在使用 raspberry pi 安装了 Microsoft IoT 和 UWP (C#) 的布局和底层算法。
我 运行 遇到的问题是检索下一个闹钟时间。
伪代码:
Select nextAlarm()
For all alarms a
if (((a.time >= now.time AND a.repeatDay == now.DayOfWeek)
OR a.repeatDay > now.DayOfWeek) AND a.dateTime < currentAlarm.dateTime)
currentAlarm = a;
然而,这将花费 O(n) 的时间来处理每个警报,并且函数 a.repeatDay > now.DayOfWeek 不是一个简单的函数(如果当天是星期三并且下一个警报打开星期一,该功能不起作用)。
我要问的是如何以上述功能起作用的方式存储警报(并且最好比 O(n) 更快)或者我如何存储所述问题已解决的重复天数。
目前正在使用 SQLite.net-pcl 套餐
闹钟和 RepeatDay class:
public class Alarm
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
[NotNull]
public string Name { get; set; }
[NotNull]
public DateTime Time { get; set; }
[NotNull]
public int Repeat { get; set; }
public Alarm(string name, DateTime time, RepeatWeek repeat)
{
this.Name = name;
this.Time = time;
this.Repeat = repeat;
}
}
public class RepeatWeek
{
int repeat = 0;
public static implicit operator int(RepeatWeek w)
{
return w.repeat;
}
public void setDay(DayOfWeek w)
{
repeat |= 1 << (int)w;
}
public void removeDay(DayOfWeek w)
{
repeat &= ~(1 << (int)w);
}
public DayOfWeek getNext(DayOfWeek d, bool inclToday = false)
{
throw new NotImplementedException();
return DayOfWeek.Monday; //Needs work
}
}
我已经尝试实现 GetNextDay。然后实现 Alarm.GetNext 就变得很简单,一个更简单的 LINQ 查询就可以满足您的要求。我留了一些给你去实现,这样你就可以说你做到了。
public class Alarm
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime Time { get; set; }
public int Repeat { get; set; }
public Alarm(string name, DateTime time, RepeatWeek repeat)
{
this.Name = name;
this.Time = time;
this.Repeat = repeat;
}
public DateTime GetNext()
{
var includeToday = true;
if (DateTime.Now.TimeOfDay > Time.TimeOfDay)
{
includeToday = false;
}
var repeat = new RepeatWeek(Repeat);
var nextDayOfWeek = repeat.GetNextDay(includeToday);
return MergeDayOfWeekAndTime(nextDayOfWeek, Time);
}
private DateTime MergeDayOfWeekAndTime(DayOfWeek? nextDayOfWeek, DateTime Time)
{
//Left as exercise to the reader.
throw new NotImplementedException();
}
}
public class RepeatWeek
{
int Repeat;
public RepeatWeek(int repeat = 0)
{
Repeat = repeat;
}
public static implicit operator int(RepeatWeek w)
{
return w.Repeat;
}
public void setDay(DayOfWeek w)
{
Repeat |= 1 << (int)w;
}
public void removeDay(DayOfWeek w)
{
Repeat &= ~(1 << (int)w);
}
public static DayOfWeek FollowingDayOfWeek(DayOfWeek day)
{
if (day == DayOfWeek.Saturday)
{
return DayOfWeek.Sunday;
}
else
{
return day + 1;
}
}
public DayOfWeek? GetNextDay(bool inclToday = false)
{
var inspect = DateTime.Now.DayOfWeek;
if (!inclToday)
{
inspect = FollowingDayOfWeek(inspect);
}
for (int i = 0; i < 7; i++)
{
if ((Repeat & (1 << (int)inspect)) > 0) return inspect;
inspect = FollowingDayOfWeek(inspect);
}
return null;
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public void GetNextDayOfWeek()
{
var repeat = new RepeatWeek();
repeat.setDay(DayOfWeek.Monday);
repeat.setDay(DayOfWeek.Tuesday);
var expected = DayOfWeek.Monday;
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
{
expected = DayOfWeek.Tuesday;
}
var actual = repeat.GetNextDay();
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void GetNextAlarm()
{
//Populate this yourself.
var alarms = new List<Alarm>();
var nextAlarm = alarms.Select(a => a.GetNext()).OrderBy(a => a.Ticks).FirstOrDefault();
}
}