2009年7月25日 星期六

空軍軍歌

上次收假回部隊後,突然來了一個大驚喜,那就是單位新來了兩位新兵,這代表我終於擺脫菜島的身份。人多好辦事,相信應該可以快快樂樂的退伍才是。

但也因這兩位新兵的加入,副主任要這兩位新兵學唱空軍軍歌,然後總班長叫我去教他們,所以我也不會唱的事也跟著露餡。不過,身為空軍卻不會唱空軍軍歌實在是說不過去,所以就趁這個時候學一下好了。



空軍軍歌
簡樸詞 劉雪庵曲

凌雲御風去,報國把志伸,遨遊崑崙上空,俯瞰太平洋濱,
看五嶽三江雄關要塞,美麗的錦繡河山,輝映著無敵機群。
緬懷先烈莫辜負創業艱辛,發揚光大尤賴我空軍軍人,
同志們努力努力,
矢勇矢勤,國祚皇皇萬世榮。

盡瘁為空軍,報國把志伸, 那怕風霜雨露,只信雙手萬能,
看鐵翼蔽空馬達齊鳴,美麗的錦繡河山,輝映著無敵機群。
我們要使技術發明日日新,我們要用血汗永固中華魂。
同志們努力努力,
同德同心,國祚皇皇萬世榮。

2009年7月6日 星期一

排列演算法

數學一向不是很好的我,一看到要列出某字串所有的排列(Permutation),就讓我非常的頭大。記得當初要準備考研究所時就曾經看著資料結構書上的解法想了老半天,似懂非懂,但最近又看到類似的題目,證明了以前是裝懂。

To iterate is human, to recurse divine.


遞迴的程式一定要在頭腦清楚時再來看,否則只是在浪費時間而已。這次,我真的看懂了。

以{a, b, c, d}為例子,要列出所有的排列,我們可以將這個問題拆解成:
  • 開頭為a加上{b, c, d}的所有排列
  • 開頭為b加上{a, c, d}的所有排列
  • 開頭為c加上{a, b, d}的所有排列
  • 開頭為d加上{a, b, c}的所有排列
所以,很明顯的是可以用遞迴方式來解。在此用C++來實作

void perm(char *obj, int pos, int n) {
if(pos == n - 1) {
for(int i = 0; i < n; ++i) cout << obj[i] << " ";
cout << endl;
}
else {
for(int i = pos; i < n; ++i) {
// swap()是要自己寫的函式,交換陣列內的值
swap(obj[pos], obj[i]);
perm(obj, pos + 1, n);
swap(obj[pos], obj[i]);
}}}

else內的for迴圈是整個程式的關鍵,可以用上面舉的例子來說明,假設obj陣列已經存了{a, b, c, d}四個值,我們呼叫perm(obj, 0, 4)來印出所有排列。for迴圈的解釋就如同將第一個位置分別用a, b, c, d為開頭,所以用了swap()把每一個值都對調到第一個位置,接著再呼叫perm(obj, 1, 4)來排列剩下的三個字元,依此類推。