2017-04-20 263 views
2

我目前正在处理具有多个(重新发生)闹钟的闹钟。从一组闹钟中获取第一个闹钟时间

我使用安装了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类:

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 
    } 
}  
+0

你只是想要下一个预定警报? – maccettura

+0

是的,我目前被困在重复的日子里 – Boe007

+0

为什么不直接勾选勾号并获得最低值? – maccettura

回答

1

我已经尽我的手来实现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(); 
    } 
} 
+0

接受,它显示了一周中的迭代。 – Boe007