剛開始接觸遞迴方法時,感覺到這種方法很匪夷所思。很多很複雜的問題短短幾行**就能解決。當時我一直試圖理清程式執行的具體過程,由於對遞迴認識不夠每次都弄的自己很暈。在這裡先不談遞迴程式執行時底層的細節,先舉幾個小例子見識一下遞迴的威力。
example1:鍊錶逆序。
對鍊錶逆序有很多辦法,如何寫乙個遞迴的函式對鍊錶逆序呢?
背景:以下為鍊錶要用到的結構體
struct node;
typedef struct node* link;
設計遞迴函式時,最重要的就是設計函式的簽名,設計函式簽名時最重要的就是設計函式所需的引數。設計函式引數時最重要的一條原則是:能夠通過引數反映函式所要解決問題的規模。
(表達的不太清楚)在該問題中該函式必須有乙個引數:指向煉表頭結點的指標link。下面是函式的簽名
link reverse (link head);
我們輸入該鍊錶的頭結點,就會對該鍊錶逆序。並返回逆序之後的頭結點。
有了該函式簽名,以後的工作就好做了。根據該函式如果我們傳入第二個結點的指標,那麼該函式就會對除去第乙個結點的鍊錶進行逆序,然後再把第乙個結點放在逆序後鍊錶的尾部就ok了。根據以上思想寫出**如下
link reverse(link head)
reverse(second);//對從第二個結點開始的鍊錶逆序。逆序之後second變為最後乙個結點。
second->next=head;//把head放在最後乙個結點之後。
return rhead;
}
雖然大體思想有了還是有很多細節要注意的1,遞迴如何結束。2不要忘了把頭結點摘下來。
解釋以下為什麼把rhead定義為static型別。函式的引數是要在棧上分配空間的,而rhead只在一次函式呼叫中用到,不必在每次函式呼叫時都為他分配空間。static型別只分配一次空間。這樣能夠節約空間。
example 2 輸出某個字串的全排列。例如輸入abc則輸出abc acb bac bca cab cba。
下面用分治的方法解決該問題。
通過觀察可以發現求abc的全排列可以分解成三個子問題:以a 開始的字串加上bc的全排列,以b 開始的字串加上ac的全排列,以c開始的字串加上ab的全排列。這樣原問題變成了三個相同的子問題,但是問題的規模減小了。(這是書本上的解法,我可想不到這種辦法。)這要能減小問題規模,一切就好辦了。
現在設計函式的簽名,函式的引數必須能夠反映我們解決問題的規模。用
void arrange(string & str , int begin,int end)作為函式簽名。為什麼引數有begin和end呢?,遞迴函式嗎?要能解決相同性質的不同規模的問題。
根據前面的思想寫出**如下:
void arrange(string & str,int begin,int end)
bool isbadposition(int ncorns)
這是乙個互動遞迴程式,只有短短的幾行**就實現了上面的演算法。表達能力有限,不解釋了。提交了。
美妙的秒殺架構
秒殺程式問題根源在於 海量的請求在爭搶有限的資源,秒殺其實和火車票非常像,都是對有限資源的搶占。這一點和微博不一樣,微博不需要加鎖,是客戶端來拉去,資源是不受限的。首先是要對於架構進行分層,最上面是展示層,其次是站點層,然後是服務層,最後才是資料層。秒殺架構的核心其實 保護資料層,因為在整套秒殺架構...
python getattr的美妙生活
一句話簡介 拿到物件是的該屬性class test age 10 def init self self.name donald staticmethod def return man print getattr test,age print getattr test,10mana a hello w...
美妙的約會C
牛牛和妞妞在一天晚上決定一起去看一場情人節演唱會,可是由於這場演唱會實在太出名了,有很多情侶都來 牛牛和妞妞不小心被 沖散了!維持秩序的人決定,讓大家排成一列,相鄰兩個進去的人 2k 1和2k,k為正整數 坐在相鄰座位。但是現在的隊伍亂糟糟的,有很多情侶都不在相鄰位置。維持秩序的人同意讓情侶們跟相鄰...