《編程珠璣》之一維向量旋轉

chapter 2 ,書中的觀點:

@1,問題定義(確定用戶的真實需求)是程序設計的根本。

@2,優秀的程序員都有點懶,他們坐下來努力思考最佳解決問題的方法,而並不急於使用最開始的想法編程。

 

第二章作者直接給出三個問題,找出一個40億個亂序的32位整數,的缺失的整數;將一個n元一維向量左旋i個位置;給定一個英文字典,找出其所有變位詞的集合。

 

第一個問題:最開始的想法,是sort後,在 i++ 遍歷一個個對比元素,時間複雜度是sort的nlog(n)。  優化的方法,是運用二分法,對於40億個元素,將其二進制表示的最高位是1的元素,分爲一類;是0的元素,分爲另一類。那麼必定有一類的元素總和,小於 2^32/2,選取該類,對該類的元素的第二個高位是1的元素,分爲一類;是0的元素,分爲另一類。那麼必定有一類的元素總和,小於 2^32/4,選取該類,進行類似的迭代。很明顯,該方法循環不超過32次,而每次的分類時間複雜度爲n,因此總的時間也是n,比第一種方法快log(n)倍!

 

第二個問題:最容易想到的,是將向量的左邊i個元素,拷貝到臨時空間,然後將右邊的n-i個元素移動到最左邊,接着把臨時空間的i個數據,拷貝到最右邊;缺點(耗空間)。如果寫個函數,函數的功能是對向量左移一位,那麼需要調用該函數i次;缺點(耗時)。如何做到不耗空間,由不耗時間呢? 除了作者稱爲"雜技"的程序,本人並沒去看。書中給出了“能滿足時間空間要求,代碼非常簡短,很難出錯”的實現方法:AB -> BA ,A求逆Ar,B求逆Br,(ArBr)r 的到 BA.  不得不佩服,用這個方法實現起來的代碼,想出錯都難!

示例: str=abcdefg,i=2, reverse(0,i-1), reverse(i,n-1), reverse(0,n-1)

                                               ba cdefg             ba gfedc             cdefgab                 (如意會不清,可想象下書中的翻手示意圖)

 

第三個問題:肯定不能強行遍歷一個單詞的所有可能組合,然後對每個組合在字典中查找驗證。作者有意展示了下“估算”的技巧,通過(π秒就是一個納世紀,也就是1年≈3.14*10^7秒)估算一個含有22個字母的單詞,排列需要數十年的運算時間! 然後給出了基於“鍵值”的方法,字典中的一個單詞的所有變位詞,都可以用唯一的一個鍵值表示。鍵值的選取,就是該單詞的字母按字段順序的排列。這個用c++的map數據結構,很容易實現。

 

期待中秋節的到來,因爲又可以放假了,現在洗澡睡覺吧!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章