鬧鐘的設計原理與實現(一)
華中科技大學 陳學友
2012年5月18日
內容摘要
現在很多人由於需要處理各種事物,但是由於某些原因可能會忘記在某個時間段需要完成的工作和其他事情,因此需要一個鬧鐘來提醒自己,避免忘記這些應該做的事情。如果只有一個提醒事件,情況非常簡單,但是對於多事件提醒的鬧鐘來說,如何解決提醒不衝突,如何使資源佔據最小是一個迫切需要解決的問題。本文介紹一個鬧鐘的設計與實現,此外還提出一種最近時間的方式來解決鬧鐘的設計問題。
關鍵詞
鬧鐘 最近時間 多時間提醒處理機制
論文內容
一、簡單的鬧鐘的設計原理
一個鬧鐘提醒包括三部分:
提醒的開始時間 |
重複週期 |
提醒的內容 |
提醒的開始時間是鬧鐘不可少的,提醒的內容是能夠有效的提醒用戶接下來要做的事情。很多鬧鐘是一次性鬧鐘,因此沒有重複的週期,比如某天去機場車站接人或者參加某個考試等。還有很多事件需要定期的重複提醒,比如朋友的生日通常一年一次,起牀鬧鐘通常每天都有。如果不設計【重複週期】,用戶每次都得輸入一個新的鬧鐘,這將是一件非常繁瑣的事。我們希望儘量能有減少這種不友好的設計,因此【重複週期】是不可少的,在這種情況下,
【重複週期】=N
就代表是單次鬧鐘了。
【重複週期】可以是每年,每月,每週,每日,每時,每小時,每分,每秒(嗯,好吧,每秒都提醒這個意義可能不是很大,至少很少有人會有這種提醒的需要),也可以是用戶自定義的時間間隔,比如是6小時等。理論上重複的週期也可以是一個世紀或者一千年。
對於多時間提醒的鬧鐘,需要生成一個提醒的列表來保存需要提醒的時間。
提醒的開始時間 |
重複週期 |
提醒的內容 |
S1 |
T1 |
Text1 |
S2 |
T2 |
Text2 |
S3 |
T3 |
Text3 |
舉例說明一下,
設系統的時鐘爲Tn,假設一個提醒時間爲
2012/5/20 13:30:00 |
每天 |
該起牀了 |
那麼我們需要提醒的時間就有
2012/5/2013:30:00
2012/5/2113:30:00
2012/5/2213:30:00
….
我們知道對於上面的例子,可以有一個簡單的實現方法,那就是檢測
Tn.Hour==13&&Tn.Mintue=30&&Tn.second==00
條件是否成立,這樣我們就能實現每天都提醒該事件的發生。同樣對於每年,每月也採用類似的方式。再如生日提醒
1990/5/20 13:30:00 |
每年 |
生日快樂 |
可以表示爲
If(Tn.Month==5&& Tn.Day==20&& Tn.Hour==13&&Tn.Mintue=30&&Tn.second==00)
{
鬧鐘提醒;
}
但是對於一個【重複週期】爲6小時的吃藥時間提醒,
2012/5/20 13:30:00 |
每5小時 |
吃藥 |
那麼我們需要提醒的時間就有
2012/5/2013:30:00
2012/5/2018:30:00
2012/5/2123:30:00
2012/5/2104:30:00
……
如果使用上面的方法就無法準確提醒了。下一節介紹如何處理這個問題。
二、複雜的鬧鐘的設計原理
爲解決上一節提出的自定義時間提醒問題,需要引入一個【真實提醒時間】。所謂【真實提醒時間】是指下一次要提醒時與系統進行比對,匹配則觸發提醒事件的鬧鐘時間。
對於
2012/5/20 13:30:00 |
每5小時 |
吃藥 |
這個提醒事件,假設當前系統時間Tn=2012/5/20 17:00:00. 那麼【真實提醒時間】只有一個,且等於2012/5/2018:30:00.
與此對應,一個鬧鐘提醒除了原有的三部分外,還要增加【真實提醒時間】:
提醒的開始時間 |
重複週期 |
提醒的內容 |
真實提醒時間 |
【真實時間】可以根據系統的當前時間動態改變。下面討論真實時間如何計算。
設S表示【提醒的開始時間】,Tv表示【真實提醒時間】,,Tc表示【重複週期】,則
Tv=S;
While(Tv<Tn)
Tv+=Tc;
最後,新的提醒事件列表就變成這樣
提醒的開始時間 |
重複週期 |
提醒的內容 |
真實提醒時間 |
S1 |
T1 |
Text1 |
Tv1 |
S2 |
T2 |
Text2 |
Tv2 |
S3 |
T3 |
Text3 |
Tv3 |
我們只需要將Tn與Tvi一一比對就可以準確的觸發提醒事件了。觸發某個事件後將
Tvi+=Tci;
就可以得到下一次的真實提醒時間列表了。
進一步優化
既然擁有了Tv這張【真實提醒時間】,我們都知道,時間是線性的,因此Tvi與Tvj必然有一個大小關係,假設 Tvmin=Min{Tvi|i=1,2,3,….};那麼我們就不需要每次都遍歷這個【真實提醒時間】列表了。在初始化和列表發生改動是重新計算Tvmin,
If(Tn==Tvmin)
{
提醒事件;
更新Tv列表;
Tvmin==Min{Tvi|i=1,2,3,….};
}