• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅信:勤能補拙

            插入排序: O(n^2),穩定排序

            插入排序是在一個已經有序的小序列的基礎上,一次插入一個元素。當然,剛開始這個有序的小序列只有1個元素,就是第一個元素。比較是從有序序列的末尾開始,也就是想要插入的元素和已經有序的最大者開始比起,如果比它大則直接插入在其后面,否則一直往前找直到找到它該插入的位置。如果碰見一個和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后順序沒有改變,從原無序序列出去的順序就是排好序后的順序,所以插入排序是穩定的。

            void
            insert_sort(
            int *array, int len)
            {
                
            int i, j, backup;
                
            for(i=1; i<=len-1++i) {
                    backup 
            = array[i];
                    
            for(j=i-1; j>=0 && array[j]>backup; --j)
                        array[j
            +1= array[j];
                    array[j
            +1= backup;
                }
            }

            void
            insert_sort_recursive(
            int *array, int len)
            {
                
            if(len == 1)
                    
            return;

                insert_sort_recursive(array, len
            -1);
                
            int j, backup = array[len-1];
                
            for(j=len-2; j>=0 && array[j]>backup; --j)
                    array[j
            +1= array[j];
                array[j
            +1= backup;
            }
            posted @ 2011-07-27 17:17 simplyzhao 閱讀(149) | 評論 (0)編輯 收藏
            選擇排序: O(n^2),非穩定排序

            選擇排序是給每個位置選擇當前元素最小的,比如給第一個位置選擇最小的,在剩余元素里面給第二個元素選擇第二小的,依次類推,直到第n-1個元素,第n個元素不用選擇了,因為只剩下它一個最大的元素了。那么,在一趟選擇,如果當前元素比一個元素小,而該小的元素又出現在一個和當前元素相等的元素后面,那么交換后穩定性就被破壞了。比較拗口,舉個例子,序列5 8 5 2 9, 我們知道第一遍選擇第1個元素5會和2交換,那么原序列中2個5的相對前后順序就被破壞了,所以選擇排序不是一個穩定的排序算法。

            void
            select_sort(
            int *array, int len)
            {
                
            int i, j, min;
                
            for(i=0; i<len-1++i) {
                    min 
            = i;
                    
            for(j=i+1; j<=len-1++j)
                        min 
            = array[min] < array[j] ? min : j;
                    
            if(min != i)
                        swap(array
            +min, array+i);
                }
            }
            posted @ 2011-07-27 15:52 simplyzhao 閱讀(122) | 評論 (0)編輯 收藏
            冒泡排序: O(n^2)時間復雜度,穩定排序

            冒泡排序就是把小的元素往前調或者把大的元素往后調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。所以,如果兩個元素相等,我想你是不會再無聊地把他們倆交換一下的;如果兩個相等的元素沒有相鄰,那么即使通過前面的兩兩交換把兩個相鄰起來,這時候也不會交換,所以相同元素的前后順序并沒有改變,所以冒泡排序是一種穩定排序算法。

            void
            swap(
            int *a, int *b) /* precondition: pointer a and b can't be the same */
            {
                
            *= *+ *b;
                
            *= *- *b;
                
            *= *- *b;
            }

            void
            bubble_sort(
            int *array, int len)
            {
                
            int i, j;
                
            for(i=0; i<len-1++i) {
                    
            for(j=len-1; j>i; --j) {
                        
            if(array[j-1> array[j])
                            swap(array
            +j-1, array+j);
                    }
                }
            }
            posted @ 2011-07-27 12:51 simplyzhao 閱讀(127) | 評論 (0)編輯 收藏
            下半年就要正式找工了,淘寶的實習因為爺爺去世提前告一段落。

            書籍

            編程語言: 《C和指針》,《C專家編程》,《C++ Primer》,《Effective C++》

            數據結構與算法: 《算法導論》,《編程珠璣》,《編程之美》

            操作系統: 《操作系統》,《深入理解計算機系統》,《Linux內核設計與實現》

            計算機網絡: 《TCP/IP詳解 卷一》


            編程實踐

            常用數據結構,排序,搜索,圖算法,動態規劃,字符串等

            參考: PKU已做題目,何海濤的面試100題,IT面試題
            posted @ 2011-07-27 10:52 simplyzhao 閱讀(545) | 評論 (2)編輯 收藏
            題目:

            題目:在數組中,數字減去它右邊的數字得到一個數對之差。求所有數對之差的最大值。例如在數組{2, 4, 1, 16, 7, 5, 11, 9}中,數對之差的最大值是11,是16減去5的結果。

            對于分治算法,實現的不好,參考原作者的思路,對于左半部分最大值、右半部分最小值都是可以在遞歸里求出的,參考:

            #include<stdio.h>
            #include
            <stdlib.h>
            #include
            <assert.h>
            #include
            <limits.h>
            #define MAX(a, b) ((a)>(b) ? (a) : (b))
            #define MIN(a, b) ((a)<(b) ? (a) : (b))
            /*
             * 題目:
             * 在數組中,數字減去它右邊的數字得到一個數對之差。求所有數對之差的最大值
             * 例如:
             * 在數組{2, 4, 1, 16, 7, 5, 11, 9}中,數對之差的最大值是11,是16減去5的結果
             
            */

            int
            naive_solution(
            int *array, int len) //O(n^2)
            {
                
            int i, j, ret = INT_MIN;
                
            for(i=0; i<len; ++i)
                    
            for(j=i+1; j<len; ++j)
                        ret 
            = MAX(ret, array[i]-array[j]);

                
            return ret;
            }

            int
            divide_and_conquer_solution(
            int *array, int begin, int end) //O(nlogn)
            {
                
            if(begin >= end)
                    
            return INT_MIN;
                
            int i, ret, left_ret, right_ret, left_max, right_min, mid;
                mid 
            = begin + ((end-begin)>>1);
                left_ret 
            = divide_and_conquer_solution(array, begin, mid);
                right_ret 
            = divide_and_conquer_solution(array, mid+1, end);
                left_max 
            = array[begin];
                
            for(i=begin+1; i<=mid; ++i)
                    left_max 
            = MAX(left_max, array[i]);
                right_min 
            = array[end];
                
            for(i=end-1; i>mid; --i)
                    right_min 
            = MIN(right_min, array[i]);

                ret 
            = MAX(left_ret, right_ret);
                ret 
            = MAX(ret, left_max-right_min);
                
            return ret;
            }

            int
            dynamic_programming_solution(
            int *array, int len) //O(n)
            {
                
            int i, cur_ret, cur_min;
                cur_ret 
            = array[len-2- array[len-1];
                cur_min 
            = MIN(array[len-2], array[len-1]);

                
            for(i=len-3; i>=0--i) {
                    cur_ret 
            = MAX(cur_ret, array[i]-cur_min);
                    cur_min 
            = MIN(cur_min, array[i]);
                }

                
            return cur_ret;
            }

            int
            main(
            int argc, char **argv)
            {
                
            int i, num, *data = NULL;
                scanf(
            "%d"&num);
                assert(num
            >=2);
                data 
            = (int *)malloc(sizeof(int* num);
                assert(data 
            != NULL);
                
            for(i=0; i<num; i++)
                    scanf(
            "%d", data+i);

                printf(
            "naive_solution result: %d\n", naive_solution(data, num));
                printf(
            "divide_and_conquer_solution result: %d\n", divide_and_conquer_solution(data, 0, num-1));
                printf(
            "dynamic_programming_solution result: %d\n", dynamic_programming_solution(data, num));

                free(data);
                
            return 0;
            }

            posted @ 2011-07-26 13:25 simplyzhao 閱讀(630) | 評論 (0)編輯 收藏
            導讀:由于Joel Spolsky的雙重身份(昔日耶魯大學計算機系學長,今日Fog Creek軟件公司的CEO),所以聽聽他的建議,對于當今無數困擾于就業壓力的中國高校計算機專業學子來說,是大有裨益的。你們會發現,大多數建議,都在強調“軟實力”的價值。

              如果你喜歡編程,那么你真是受到了上天的眷顧。你是非常幸運的少數人之一,能夠以自己喜歡的事謀生。大多數人沒有這么幸運。你認為理所當然的觀念“熱愛你的工作”,其實是一個很現代的概念。通常的看法是,工作是一種讓人很不開心的事,你為了拿工資才不得不去上班。你工作的目的是為了攢下錢去干那些自己真正喜歡干的事,但是前提是你得等到65歲退休之后才行,而且還有不少條件。條件一,你的積蓄必須足夠多;條件二,你沒有老到走不動,你還有體力去干那些事情;條件三,你喜歡的事情不需要用到脆弱的膝蓋、昏花的視力,也不要求你走上一里地不喘氣,等等。

              我剛才說到哪里了?對了,我要提建議。

              畢業前練好寫作

              如果不是Linus Torvalds不斷地散布福音,請問Linux操作系統會成功嗎?雖然他是一個非常聰明的計算機天才,但是Linux吸引來全世界一大批志愿者的真正原因卻是Linus Torvalds的表達能力。他通過電子郵件和郵件列表用書面形式傳播自己的想法,最終引起了所有人的注意。

              你聽說過現在風靡一時的“極限編程”(Extreme Programming)嗎?我在這個地方不談我對極限編程的看法,我只說如果你聽過這個詞,那么原因就是它的倡導者都是一些非常有才華的作家和演說家。

              即使我們縮小范圍,將目光局限在任何一個軟件開發團體中,你也會發現該團體中最有權勢和影響力的程序員正是那些表達能力強的程序員,他們無論是做書面表達還是做口頭表達,都能夠清晰、自如、具有說服力地傳達觀點。此外,長得高也有助于提升影響力,不過這個不取決于你。

              一個普通程序員與一個優秀程序員的區別,不在于他們懂得的編程語言誰多誰少,也不在于他們喜歡用Python語言還是喜歡用Java語言,而在于他們能否與他人交流思想。如果你能說服其他人,你的力量就可以得到放大。如果你能寫出清晰的注釋和技術規格說明書,其他程序員就能夠理解你的代碼,因此他們就能在自己的代碼中使用,而不必重寫。如果你做不到這一點,你的代碼對其他人就沒有價值。如果你能為最終用戶寫出清晰的使用手冊,其他人就能明白你的代碼是用來干什么的,這是唯一讓別人明白你的代碼有何價值的方法。SourceForge[ ]上有許多優美的、有用的代碼,但是它們都像被埋葬了一樣,根本沒人來用,原因就是它們的作者沒有寫好使用說明(或者壓根就沒寫)。這樣一來就沒有人知道他們的成果,他們杰出的代碼就衰亡了。

              如果一個程序員不會用英語寫作、沒有良好的寫作能力,我就不會雇他。如果你能寫,不管你去哪家公司工作,你很快就會發現寫作技術文檔的任務會落到你頭上,這意味著你已經開始在放大自己的影響力了,管理層正在注意到你。

              大學里有些課程被公認為“寫作密集型”(writing intensive)課程,這就是說為了拿到學分,你必須寫作多得可怕的文字。一定要去上這樣的課程!不要管學科,只要這門課每周甚至每天都要你寫東西,你就去上。

              你還可以動手寫日記或者網志。你寫得越多,寫作就會變得越容易。寫起來越容易,你就會寫得越多。這是一個良性循環。

              畢業前學好C語言

              第二點我要講的是C語言。請注意,我說的是C語言,而不是C++。雖然在實際使用中C語言已經越來越罕見,但是它仍然是當前程序員的共同語言。C語言讓程序員互相溝通,更重要的是,它比你在大學中學到的“現代語言”(比如ML語言、Java語言、Python語言或者其它正在教授的流行垃圾語言)都更接近機器。你至少需要花一個學期來了解機器原理,否則你永遠不可能在高級語言的層次寫出高效的代碼。你也永遠無法開發編譯器和操作系統,而它們恰恰屬于目前程序員能夠得到的最佳工作之列。別人也永遠不會放心將大型項目的架構設計交給你。我不管你懂多少延續(continuation)、閉包(closure)、異常處理(exception handling),只要你不能解釋為什么while (*s++ = *t++);這句代碼的作用是復制字符串,或者不覺得這是世界上對你來說再自然不過的事情,那么你就是在盲目無知的情況下編程。在我看來,這就好像一個醫生不懂得最基本的解剖學就在開處方,他看病的根據完全是因為那些娃娃臉的醫藥廠商銷售代表說這種藥有用。

              畢業前學好微觀經濟學

              如果你沒有上過任何經濟學課程,那么我首先來做一個超短的評論:經濟學是這樣的學科之一,剛開始學的時候轟轟烈烈,有許多有用的、言之有理的理論和可以在真實世界中得到證明的事實,等等;但是,再學下去就每況愈下,有用的東西就不多了。經濟學一開始那個有用的部分正是微觀經濟學,它是商業領域所有重要理論的基礎。跟在微觀經濟學后面的東西就不行了。你接下來學的是宏觀經濟學,如果你愿意,盡管跳過去,也不會有什么損失。宏觀經濟學開頭的部分是利息理論,內容比方說是利率與失業之間的關系,但是怎么說呢,看上去這部分里面還沒有被證實的東西多于已經被證實的東西。學完這部分,后面的內容越來越糟糕,許多經濟學專業的學生實際上都變成在搞物理學,因為這樣才能在華爾街上找到更好的工作。但是不管怎樣,你一定要去學微觀經濟學,因為你必須搞懂供給和需求,你必須明白競爭優勢,你必須理解什么是凈現值(NPV),什么是貼現,什么是邊際效用。只有這樣,你才會懂得為什么生意是現在這種做法。

              為什么計算機系的學生也應該學經濟學?因為,從經營一家公司的角度來看,比起那些不懂的程序員,一個理解基本商業規則的程序員將會更有價值。就是這么簡單。我無法告訴你有多少次我是那樣地充滿挫折感,因為我看到了太多的提出一些瘋狂的想法的程序員,這些想法在代碼上也許可行,但在資本主義世界中毫無意義。如果你懂得商業規則,你就是一個更有價值的程序員,你會因此得到回報的,但是前提是你要去學習微觀經濟學。

              不要因為枯燥就不選修非計算機專業的課程

              想提高GPA績點的一個好方法就是多選修非計算機系的課程。請千萬不要低估你的GPA的重大意義。千千萬萬的人事經理和招聘人員在拿到一份簡歷的時候,第一眼就會去看GPA,包括我也是這樣。我們不會為這種做法道歉。為什么?因為GPA不反映單個的成績,而是代表了許多個教授在一段很長的時間中,在不同的情況下,對你的表現的一個總的評估。SAT成績難道不夠嗎?哈,那只不過是一場幾個小時的測試罷了。GPA中包括了四年大學期間你的小論文、期中考試和課堂表現,總數有幾百次之多。當然,GPA也有自己的問題,不是百分之百準確。比如,這些年來,老師對學生的打分越來越寬松,學習成績有通貨膨脹的趨勢。再比如,GPA無法反映課程的難度,沒人能夠看出你的GPA是來自無名社區大學家政系的輕松課程還是來自加州理工學院針對研究生的量子力學課程。漸漸地,我形成了一套自己的做法,首先我會過濾掉所有來自社區大學、GPA低于2.5的簡歷,然后我會要求剩下的人給我寄成績單和推薦信。我再從中發現那些成績一貫優秀的人,而不是那些僅僅在計算機系課程中得到高分的人。

              為什么我要關心某人的“歐洲歷史”課程成績呢,畢竟作為雇主我要找的應該是程序員啊?何況,歷史是那么枯燥,不得高分很正常。哦,這么說來,你的意思是我應該雇用你,而不用考慮一旦工作變得枯燥你會不會努力工作?別忘了,在編程工作中也有很枯燥的東西。每一項工作都有枯燥難耐的時刻。我不想雇用那些只想干有趣事情的人。

              選修有大量編程實踐的課程

              我依然清楚記得我發誓絕不讀研究生的那一刻。那是在一門叫做“動態邏輯”的課程上,教師是活力十足的耶魯大學教授Lenore Zuck,她是計算機系那些聰明的老師中最聰明的人之一。

              如今, 由于記憶力糟糕, 我已經差不多把這門課的內容忘光了,但是不管怎么說,在這里我還是想要對付著說一下。大致上,形式邏輯的意思是說,如果條件成立,你就能證明結論也成立。比如,根據形式邏輯,已知“只要成績好,就能被雇用”,然后假定“Johnny的成績好”,你就可以得到一個嶄新的結論“Johnny會被雇用”。這完全是經典方法。但是,一個解構主義者(deconstructionist)只需要10秒鐘就能破壞形式邏輯中所有有用的東西。這樣一來,留給你的只是一些趣味性,而不是實用性。

              現在再來說動態邏輯。它與形式邏輯其實是一回事,但是必須再多考慮時間因素。比如,“你打開燈之后,就能看見自己的鞋子”,已知“燈以前是亮的”,那么這就意味著“你看見了自己的鞋子”。

              對于像Zuck教授那樣聰明的理論家,動態邏輯充滿了吸引力,因為它看上去很有希望讓你在形式上證明一些計算機程序的相關理論問題。這樣做說不定很有用。比如,你可以用它在形式上證明,火星漫游車的閃存卡不會發生溢出(overflow)問題,不會因而整天一遍又一遍地重啟,耽誤了它在那顆赤紅色的星球上漫游尋找火星人馬文(Marvin the Martian)。

              在第一堂課上,Zuck博士寫滿了整整兩面黑板,甚至黑板旁邊的墻上都寫上了很多證明步驟。需要證明的問題是,有一個控制燈泡的開關,現在燈泡沒有亮,這時你打開了開關,請證明燈泡將會點亮。

              整個證明過程復雜得不可思議,處處都是陷阱,必須十分小心。保證這個證明不出錯太困難了,還不如直接相信打開開關燈就會亮。真的,雖然證明過程寫滿了許多塊黑板,但是還是有許多中間步驟被省略了,因為如果要從形式邏輯上完整證明所有步驟,那就瑣碎得無法形容了。許多步驟是用各種經典的邏輯證明方法推導得到的,包括歸納法、反證法等,甚至有些部分還是由旁聽的研究生證明的。

              留給我們的課后作業是證明逆命題:如果燈原來是關著的,現在卻亮了,那么請證明開關的狀態一定同原來相反。

              我動手開始證明,我真的去證明了。

              我在圖書館里待了很長時間。

              我對照著Zuck博士的原始證明想依樣畫葫蘆。研究了幾個小時之后,我在其中發現了一個錯誤。可能我抄寫的時候抄錯了,但是這使得我想通了一件事。如果花費3個小時,寫滿了一塊又一塊的黑板,每一秒鐘都可能出錯,最后能夠證明的卻只是一個很瑣碎的結論,那么這種方式有多大的實用性呢?在活生生、充滿趣味的現實世界中,你永遠都不會有機會使用它。

              但是,動態邏輯的理論家們對這一點不感興趣。他們看上它不是因為它有用,而是因為它可以為他們帶來終身教職。

              我放棄了這門課,并且發誓絕不會去讀計算機科學的研究生。

              這個故事告訴我們,計算機科學與軟件開發不是一回事。如果你真的非常幸運,你的學校可能會開設很像樣的軟件開發課程。但是另一種可能是,你的學校根本不教你在現實中如何編程,因為精英學校都覺得,教授工作技能最好留給職業技術學校、犯人重返社會的培訓項目去做。你到處都能學怎么寫代碼。別忘了,我們是耶魯大學,我們的使命是培養未來的世界領袖。你交了16萬美元的學費,卻在學循環語句的寫法,這怎么可以?你以為這是什么地方,難道是機場沿途的酒店里臨時拼湊起來不靠譜的Java語言培訓班?哼哼。

              麻煩在于我們沒有一種真正教授軟件開發的專門學校。你如果想成為一個程序員,你可能只能選擇計算機科學專業。這是一個不錯的專業,但是它同軟件開發不是一回事。在那些400等級的課程代號中,去尋找名稱中帶有“Practicum”這個詞的課程吧(編者注:指供人實習的課程)。不要被這個拉丁語單詞嚇倒,這些都是有用的課程,之所以起這種名字,只是為了讓那些文縐縐、裝腔作勢、滿嘴胡說八道的公司經理們覺得高深莫測。

              別擔心所有工作都被印度人搶走

              我首先要說的是,如果你本身就已經在印度了,或者你就是印度人,那么你真的毫無必要去想這件事,根本不用琢磨所有的工作機會是不是都跑到了印度。那些都是非常好的工作,好好地享受吧,祝你身體健康。

              但是,我不斷聽說計算機系的入學人數下降得很厲害,已經到了危險的程度。根據我聽到的說法,其中的一個原因是“學生們不愿去學一個工作機會都流向印度的專業”。這種擔心大錯特錯,有很多理由可以反駁。首先,根據一時性的商業潮流決定個人的職業選擇,這是愚蠢的。其次,即使編程工作無一幸存地都流向了印度和中國,但是學習編程本身依然是一種第一流的素質訓練,可以為各種超級有趣的工作打下基礎,比如業務流程工程(business process engineering)。再次,不管是在美國還是在印度,真正優秀的程序員依然是非常非常短缺的,這一點請相信我。不錯,確實有相當一批失業的IT從業者在那里鼓噪,抱怨他們長時間找不到工作,但是你知道嗎?即使冒著觸怒這些人的風險,我還是要說,真正優秀的程序員根本不會失業。最后,你還能找到更好的專業嗎?你覺得什么專業好?主修歷史學?如果那樣,你畢業的時候就會發現,根本沒有其他選擇,只能去法學院。不過我倒是知道一件事:99%的律師都痛恨他們的工作,痛恨他們當律師的每一分鐘。可是,律師每周的工作時間偏偏長達90小時。就像我前面說過的:如果你喜歡編程,那么你真是受到了上天的眷顧。你是非常幸運的少數人之一,能夠以自己喜歡的事謀生。

              不過說實話,我不覺得學生們真的有上面的想法。近年來,計算機系入學人數的下降只是回到了歷史上的正常水平,因為前些年的互聯網狂熱使得入學人數出現了大泡沫,抬高了基數。由于這種泡沫,許多并不真的喜歡編程的人也來讀計算機系。他們心里想的是,只要進了計算機系,將來就能找到誘人的高薪工作,就能獲得24歲當上CEO、進行IPO的機會。謝天謝地,這些人現在都離計算機系遠遠的了。

              找一份好的暑期實習工作

              精明的招聘負責人都知道,喜歡編程的人高中時就將牙醫的信息輸入了數據庫,進入大學前就去過三次電腦夏令營,為校報做過內容管理系統,有過軟件公司的夏季實習經歷。招聘負責人就是要在你的簡歷上找這些東西。

              如果你喜歡編程, 就不要隨便什么工作都答應,否則你會犯下最大的錯誤。不管是暑期工作,還是兼職或者其他性質的工作,只要與編程無關,就不要輕易接受。我知道,其他19歲的孩子都想去購物中心里打工,在那里折疊襯衫。但是你與他們不同,你19歲時就已經掌握了一門非常有價值的技能。將時間浪費在折疊襯衫上是很愚蠢的,等到畢業的時候,你的簡歷上本應該寫滿了一大堆與編程相關的經歷。就讓那些財經類的畢業生去租車公司“幫助人們滿足他們租車的需要”吧,你要干的是別的事(在電視中扮演超人的Tom Welling注1除外)。

              為了讓你的生活變得更容易一些,也為了強調這整篇文章完全是為了滿足我的個人目的,我要告訴你,我的公司——Fog Creek軟件公司——提供軟件開發方面的暑期實習機會。我們非常看重簡歷。“比起其他公司的實習工作,你在Fog Creek最有可能學到更多的編寫代碼、軟件開發、商業運作方面的知識。”這是去年夏天我們的一個實習生Ben說的。他會這樣說,并不完全是因為我派了人到他的宿舍讓他這樣說。我們接受實習申請的截止日期是2月1日。一起來吧。

              如果你聽從了我的建議,你還是有可能落得一個悲慘的下場,比如很早就賣掉了微軟公司的股票,再比如拒絕了谷歌公司的工作機會,原因是你想要一間自己的可以關上門的獨立辦公室,或者做出了其他生命中愚蠢的決定。但是,這些可不是我的錯。我一開始就告訴過你,不要聽我的話。


              本文轉載自《軟件隨想錄》(作者:Joel Spolsky ,譯者: 阮一峰,2009年12月出版)
            posted @ 2011-07-24 10:02 simplyzhao 閱讀(235) | 評論 (0)編輯 收藏
                 摘要: 來源: http://coolshell.cn/articles/4990.html月光博客6月12日發表了《寫給新手程序員的一封信》,翻譯自《An open letter to those who want to start programming》,我的朋友(他在本站的id是Mailper)告訴我,他希望在酷殼上看到一篇更具操作性的文章。因為他也是喜歡編程和技術的家伙,于是,我讓他把...  閱讀全文
            posted @ 2011-07-24 09:57 simplyzhao 閱讀(211) | 評論 (0)編輯 收藏
            問題:

            Given a random number generator which can generate the number in range (1,5) uniformly. How can you use it to build a random number generator which can generate the number in range (1,7) uniformly?


            (給定一個隨機數生成器,這個生成器能均勻生成1到5(1,5)的隨機數,如何使用這個生成器生成均勻分布的1到7(1,7)的數?)

            解法一:
            拒絕采樣定理
            簡單的說, 把 1-5 的隨機數發生器用兩次, 拼成一個5進制的數, 就是1-25. 將這 1-25 平均分配的25種情況映射到7種情況上, 問題就解決了. 因為21是7的倍數, 我們可以每三個映射到一個, 即1-3 映射到1, …, 19-21 映射到7. 可見, 這些情況之間的概率是一樣的. 那么, 要是拼成的數字正好是 22-25 這四個呢? 有兩種方法, 第一種是丟棄這個數字, 從頭再來, 直到拼成的數字在1-21之間. 因為這個是個概率算法, 不能保證每次都能落在1-21, 所以采樣的密度不高. 還有一種方法, 是說, 假如落到了 22-25, 那這次的采樣結果就用上次的. 可以證明, 這看上去兩個互相矛盾的算法, 結果都能均等的得到等概率的分布. (前者叫做 Reject Sampling, 后者叫做 Metropolis Algorithm, 都是數學物理模擬里面常用的方法)

            解法二:
            二進制
            1-2映射到0,3跳過,4-5映射到1
            生成三位的二進制即可
            posted @ 2011-07-19 19:57 simplyzhao 閱讀(3496) | 評論 (0)編輯 收藏
            問題來源: 編程珠璣

            解法一:
            遍歷這n個items,巧妙地利用概率來篩選
            void
            generate_random_m_from_n(
            int n, int m)
            {
                
            int i, remaining, select = m;
                srand(time(NULL));
                
            for(i=0; i<n; i++) {
                    remaining 
            = n - i;
                    
            if(rand()%remaining < select) {
                        printf(
            "%d\t", i);
                        
            --select;
                    }
                }
                printf(
            "\n");
            }

            解法二:
            shuffle,即隨機洗牌程序,然后選擇前m個items即可
            代碼參考: http://blog.fuqcool.com/2011/04/17/algorithm-shuffle.html

            洗牌算法的一種實現

            作者:fuqcool 發布時間:2011-04-17 23:16:02 分類: algorithms

            最近自己在做一個小的程序,需要把一個集合里面的元素全部隨機地打散。自己想了一個方法,復雜度是n,覺得不太快。后來參照了一下python關于shuffle的算法,發現我的方法跟它的是一樣的,連python的代碼都這么寫,可能已經沒有辦法再快了吧!

            下面就來介紹洗牌算法,用C語言描述。

            算法的前提是有一個產生隨機數的函數

            // Generates a random integer between beg and end.
            int GetRandomNumber(int beg, int end);

            還有一個交換函數。

            // Swap a and b.
            void Swap(int a, int b);

            上面兩個函數我就不寫出實現了,因為這篇文章的重點在于算法的討論。

            假設我們有一堆撲克牌,怎么才能把這副牌完全打亂呢?計算機當然不能像人手那樣洗牌。但是它可以產生隨機數,隨機地從一副牌中抽出一張牌是可以的。既然這樣那就好辦了,我們不停地從牌堆中隨機抽取一張撲克牌,然后把這些牌堆起來,直到原來的牌堆只剩下一張牌的時候為止。這樣不就完成了洗牌的動作了嗎。

            下面是C代碼:

            int Shuffle(int[] a, int len)
            {
                for (int i = len - 1; i > 0; i--)
                {
                    // Select an element from index 0 to i randomly;
                    int index = GetRandomNumber(0, i);
                    // exchange a[i] with a[index]
                    Swap(a[index], a[i]);
                }
            }

            順便也貼出python的random單元關于shuffle的實現:

            def shuffle(self, x, random=None, int=int):
                """x, random=random.random -> shuffle list x in place; return None.
            
                Optional arg random is a 0-argument function returning a random
                float in [0.0, 1.0); by default, the standard random.random.
                """
            
                if random is None:
                    random = self.random
                for i in reversed(xrange(1, len(x))):
                    # pick an element in x[:i+1] with which to exchange x[i]
                    j = int(random() * (i+1))
                    x[i], x[j] = x[j], x[i]

            posted @ 2011-07-18 09:32 simplyzhao 閱讀(464) | 評論 (0)編輯 收藏
            來源:
            http://coolshell.cn/articles/3345.html

            Software Engineer
            • Why are manhole covers round? (陳皓:為什么下水井蓋是圓的?這是有N種答案的,上Wiki看看吧)
            • What is the difference between a mutex and a semaphore? Which one would you use to protect access to an increment operation?
            • A man pushed his car to a hotel and lost his fortune. What happened? (陳皓:腦筋急轉彎?他在玩大富翁游戲?!!)
            • Explain the significance of “dead beef”.(陳皓:要是你看到的是16進制 DEAD BEEF,你會覺得這是什么?IPv6的地址?)
            • Write a C program which measures the the speed of a context switch on a UNIX/Linux system.
            • Given a function which produces a random integer in the range 1 to 5, write a function which produces a random integer in the range 1 to 7.(陳皓:上StackOverflow看看吧,經典的問題)
            • Describe the algorithm for a depth-first graph traversal.
            • Design a class library for writing card games. (陳皓:用一系列的類來設計一個撲克游戲,設計題)
            • You need to check that your friend, Bob, has your correct phone number, but you cannot ask him directly. You must write a the question on a card which and give it to Eve who will take the card to Bob and return the answer to you. What must you write on the card, besides the question, to ensure Bob can encode the message so that Eve cannot read your phone number?(陳皓:協議+數字加密,我試想了一個,紙條上可以這樣寫,“Bob,請把我的手機號以MD5算法加密后的字符串,比對下面的字符串——XXXXXX,它們是一樣的嗎?”)
            • How are cookies passed in the HTTP protocol?
            • Design the SQL database tables for a car rental database.
            • Write a regular expression which matches a email address. (陳皓:上StackOverflow查相當的問題吧。)
            • Write a function f(a, b) which takes two character string arguments and returns a string containing only the characters found in both strings in the order of a. Write a version which is order N-squared and one which is order N.(陳皓:算法題,不難,不說了。一個O(n^2)和一個O(n)的算法復雜度)
            • You are given a the source to a application which is crashing when run. After running it 10 times in a debugger, you find it never crashes in the same place. The application is single threaded, and uses only the C standard library. What programming errors could be causing this crash? How would you test each one? (陳皓:和隨機數有關系?或是時間?)
            • Explain how congestion control works in the TCP protocol.
            • In Java, what is the difference between final, finally, and finalize?
            • What is multithreaded programming? What is a deadlock?
            • Write a function (with helper functions if needed) called to Excel that takes an excel column value (A,B,C,D…AA,AB,AC,… AAA..) and returns a corresponding integer value (A=1,B=2,… AA=26..).
            • You have a stream of infinite queries (ie: real time Google search queries that people are entering). Describe how you would go about finding a good estimate of 1000 samples from this never ending set of data and then write code for it.
            • Tree search algorithms. Write BFS and DFS code, explain run time and space requirements. Modify the code to handle trees with weighted edges and loops with BFS and DFS, make the code print out path to goal state.
            • You are given a list of numbers. When you reach the end of the list you will come back to the beginning of the list (a circular list). Write the most efficient algorithm to find the minimum # in this list. Find any given # in the list. The numbers in the list are always increasing but you don’t know where the circular list begins, ie: 38, 40, 55, 89, 6, 13, 20, 23, 36. (陳皓:循環排序數組的二分查找問題)
            • Describe the data structure that is used to manage memory. (stack)
            • What’s the difference between local and global variables?
            • If you have 1 million integers, how would you sort them efficiently? (modify a specific sorting algorithm to solve this)
            • In Java, what is the difference between static, final, and const. (if you don’t know Java they will ask something similar for C or C++).
            • Talk about your class projects or work projects (pick something easy)… then describe how you could make them more efficient (in terms of algorithms).
            • Suppose you have an NxN matrix of positive and negative integers. Write some code that finds the sub-matrix with the maximum sum of its elements.(陳皓:以前見過一維數組的這個問題,現在是二維的。感覺應該是把二維的第一行的最大和的區間算出來,然后再在這個基礎之上進行二維的分析。思路應該是這個,不過具體的算法還需要想一想)
            • Write some code to reverse a string.
            • Implement division (without using the divide operator, obviously).(陳皓:想一想手算除法的過程。)
            • Write some code to find all permutations of the letters in a particular string.
            • What method would you use to look up a word in a dictionary? (陳皓:使用排序,哈希,樹等算法和數據結構)
            • Imagine you have a closet full of shirts. It’s very hard to find a shirt. So what can you do to organize your shirts for easy retrieval?
            • You have eight balls all of the same size. 7 of them weigh the same, and one of them weighs slightly more. How can you fine the ball that is heavier by using a balance and only two weighings?
            • What is the C-language command for opening a connection with a foreign host over the internet?
            • Design and describe a system/application that will most efficiently produce a report of the top 1 million Google search requests. These are the particulars: 1) You are given 12 servers to work with. They are all dual-processor machines with 4Gb of RAM, 4x400GB hard drives and networked together.(Basically, nothing more than high-end PC’s) 2) The log data has already been cleaned for you. It consists of 100 Billion log lines, broken down into 12 320 GB files of 40-byte search terms per line. 3) You can use only custom written applications or available free open-source software.
            • There is an array A[N] of N numbers. You have to compose an array Output[N] such that Output[i] will be equal to multiplication of all the elements of A[N] except A[i]. For example Output[0] will be multiplication of A[1] to A[N-1] and Output[1] will be multiplication of A[0] and from A[2] to A[N-1]. Solve it without division operator and in O(n).(陳皓:注意其不能使用除法。算法思路是這樣的,把output[i]=a[i]左邊的乘積 x a[i]右邊的乘積,所以,我們可以分兩個循環,第一次先把A[i]左邊的乘積放在Output[i]中,第二次把A[i]右邊的乘積算出來。我們先看第一次的循環,使用迭代累積的方式,代碼如下:for(r=1; i=0; i<n-1; i++){ Output[i]=r; r*=a[i]; },看明白了吧。第二次的循環我就不說了,方法一樣的。)
            • There is a linked list of numbers of length N. N is very large and you don’t know N. You have to write a function that will return k random numbers from the list. Numbers should be completely random. Hint: 1. Use random function rand() (returns a number between 0 and 1) and irand() (return either 0 or 1) 2. It should be done in O(n).(陳皓:本題其實不難。在遍歷鏈表的同時一邊生成隨機數,一邊記錄最大的K個隨機數和其鏈接地址。)
            • Find or determine non existence of a number in a sorted list of N numbers where the numbers range over M, M>> N and N large enough to span multiple disks. Algorithm to beat O(log n) bonus points for constant time algorithm.(陳皓:使用bitmap,如果一個長整形有64位,那么我們可以使用M/64個bitmap)
            • You are given a game of Tic Tac Toe. You have to write a function in which you pass the whole game and name of a player. The function will return whether the player has won the game or not. First you to decide which data structure you will use for the game. You need to tell the algorithm first and then need to write the code. Note: Some position may be blank in the game? So your data structure should consider this condition also.
            • You are given an array [a1 To an] and we have to construct another array [b1 To bn] where bi = a1*a2*…*an/ai. you are allowed to use only constant space and the time complexity is O(n). No divisions are allowed.(陳皓:前面說過了)
            • How do you put a Binary Search Tree in an array in a efficient manner. Hint :: If the node is stored at the ith position and its children are at 2i and 2i+1(I mean level order wise)Its not the most efficient way.(陳皓:按順序遍歷樹)
            • How do you find out the fifth maximum element in an Binary Search Tree in efficient manner. Note: You should not use use any extra space. i.e sorting Binary Search Tree and storing the results in an array and listing out the fifth element.
            • Given a Data Structure having first n integers and next n chars. A = i1 i2 i3 … iN c1 c2 c3 … cN.Write an in-place algorithm to rearrange the elements of the array ass A = i1 c1 i2 c2 … in cn(陳皓:這個算法其實就是從中間開始交換元素,代碼:for(i=n-1; i>1; i++) {  for(j=i; j<2*n-i; j+=2) { swap(a[j], a[j+1]); } },不好意思寫在同一行上了。)
            • Given two sequences of items, find the items whose absolute number increases or decreases the most when comparing one sequence with the other by reading the sequence only once.
            • Given That One of the strings is very very long , and the other one could be of various sizes. Windowing will result in O(N+M) solution but could it be better? May be NlogM or even better?
            • How many lines can be drawn in a 2D plane such that they are equidistant from 3 non-collinear points?
            • Let’s say you have to construct Google maps from scratch and guide a person standing on Gateway of India (Mumbai) to India Gate(Delhi). How do you do the same?
            • Given that you have one string of length N and M small strings of length L. How do you efficiently find the occurrence of each small string in the larger one?
            • Given a binary tree, programmatically you need to prove it is a binary search tree.
            • You are given a small sorted list of numbers, and a very very long sorted list of numbers – so long that it had to be put on a disk in different blocks. How would you find those short list numbers in the bigger one?
            • Suppose you have given N companies, and we want to eventually merge them into one big company. How many ways are theres to merge?
            • Given a file of 4 billion 32-bit integers, how to find one that appears at least twice? (陳皓:我能想到的是拆分成若干個小數組,排序,然后一點點歸并起來)
            • Write a program for displaying the ten most frequent words in a file such that your program should be efficient in all complexity measures.(陳皓:你可能需要看看這篇文章Finding Frequent Items in Data Streams
            • Design a stack. We want to push, pop, and also, retrieve the minimum element in constant time.
            • Given a set of coin denominators, find the minimum number of coins to give a certain amount of change.(陳皓:你應該查看一下這篇文章:Coin Change Problem
            • Given an array, i) find the longest continuous increasing subsequence. ii) find the longest increasing subsequence.(陳皓:這個題不難,O(n)算法是邊遍歷邊記錄當前最大的連續的長度。)
            • Suppose we have N companies, and we want to eventually merge them into one big company. How many ways are there to merge?
            • Write a function to find the middle node of a single link list. (陳皓:我能想到的算法是——設置兩個指針p1和p2,每一次,p1走兩步,p2走一步,這樣,當p1走到最后時,p2就在中間)
            • Given two binary trees, write a compare function to check if they are equal or not. Being equal means that they have the same value and same structure.(陳皓:這個很簡單,使用遞歸算法。)
            • Implement put/get methods of a fixed size cache with LRU replacement algorithm.
            • You are given with three sorted arrays ( in ascending order), you are required to find a triplet ( one element from each array) such that distance is minimum. Distance is defined like this : If a[i], b[j] and c[k] are three elements then distance=max(abs(a[i]-b[j]),abs(a[i]-c[k]),abs(b[j]-c[k]))” Please give a solution in O(n) time complexity(陳皓:三個指針,a, b, c分別指向三個數組頭,假設:a[0]<b[0]<c[0],推進a直到a[i]>b[0],計算 abs(a[i-1] – c[0]),把結果保存在min中。現在情況變成找 a[i], b[0],c[0],重復上述過程,如果有一個新的值比min要小,那就取代現有的min。)
            • How does C++ deal with constructors and deconstructors of a class and its child class?
            • Write a function that flips the bits inside a byte (either in C++ or Java). Write an algorithm that take a list of n words, and an integer m, and retrieves the mth most frequent word in that list.
            • What’s 2 to the power of 64?
            • Given that you have one string of length N and M small strings of length L. How do you efficiently find the occurrence of each small string in the larger one? (陳皓:我能想到的是——把那M個小字串排個序,然后遍歷大字串,并在那M個字串中以二分取中的方式查找。)
            • How do you find out the fifth maximum element in an Binary Search Tree in efficient manner.
            • Suppose we have N companies, and we want to eventually merge them into one big company. How many ways are there to merge?
            • There is linked list of millions of node and you do not know the length of it. Write a function which will return a random number from the list.
            • You need to check that your friend, Bob, has your correct phone number, but you cannot ask him directly. You must write a the question on a card which and give it to Eve who will take the card to Bob and return the answer to you. What must you write on the card, besides the question, to ensure Bob can encode the message so that Eve cannot read your phone number?
            • How long it would take to sort 1 trillion numbers? Come up with a good estimate.
            • Order the functions in order of their asymptotic performance: 1) 2^n 2) n^100 3) n! 4) n^n
            • There are some data represented by(x,y,z). Now we want to find the Kth least data. We say (x1, y1, z1) > (x2, y2, z2) when value(x1, y1, z1) > value(x2, y2, z2) where value(x,y,z) = (2^x)*(3^y)*(5^z). Now we can not get it by calculating value(x,y,z) or through other indirect calculations as lg(value(x,y,z)). How to solve it?
            • How many degrees are there in the angle between the hour and minute hands of a clock when the time is a quarter past three?
            • Given an array whose elements are sorted, return the index of a the first occurrence of a specific integer. Do this in sub-linear time. I.e. do not just go through each element searching for that element.
            • Given two linked lists, return the intersection of the two lists: i.e. return a list containing only the elements that occur in both of the input lists. (陳皓:把第一個鏈表存入hash表,然后遍歷第二個鏈表。不知道還沒有更好的方法。)
            • What’s the difference between a hashtable and a hashmap?
            • If a person dials a sequence of numbers on the telephone, what possible words/strings can be formed from the letters associated with those numbers?(陳皓:這個問題和美國的電話有關系,大家可以試著想一下我們發短信的手機,按數字鍵出字母,一個組合的數學問題。)
            • How would you reverse the image on an n by n matrix where each pixel is represented by a bit?
            • Create a fast cached storage mechanism that, given a limitation on the amount of cache memory, will ensure that only the least recently used items are discarded when the cache memory is reached when inserting a new item. It supports 2 functions: String get(T t) and void put(String k, T t).
            • Create a cost model that allows Google to make purchasing decisions on to compare the cost of purchasing more RAM memory for their servers vs. buying more disk space.
            • Design an algorithm to play a game of Frogger and then code the solution. The object of the game is to direct a frog to avoid cars while crossing a busy road. You may represent a road lane via an array. Generalize the solution for an N-lane road.
            • What sort would you use if you had a large data set on disk and a small amount of ram to work with?
            • What sort would you use if you required tight max time bounds and wanted highly regular performance.
            • How would you store 1 million phone numbers?(陳皓:試想電話是有區段的,可以把區段統一保存,Flyweight設計模式)
            • Design a 2D dungeon crawling game. It must allow for various items in the maze – walls, objects, and computer-controlled characters. (The focus was on the class structures, and how to optimize the experience for the user as s/he travels through the dungeon.)
            • What is the size of the C structure below on a 32-bit system? On a 64-bit? (陳皓:注意編譯器的對齊)

            struct foo {

            char a;
            char* b;
            };
            posted @ 2011-07-14 10:13 simplyzhao 閱讀(558) | 評論 (0)編輯 收藏
            僅列出標題
            共21頁: 1 2 3 4 5 6 7 8 9 Last 

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久亚洲AV无码专区网站| 久久久久久午夜成人影院| 国产精品久久久久蜜芽| 久久久久无码精品国产不卡| 好久久免费视频高清| 美女久久久久久| AV无码久久久久不卡蜜桃 | 久久天堂AV综合合色蜜桃网 | 亚洲国产成人久久一区WWW| 囯产精品久久久久久久久蜜桃| 日本道色综合久久影院| 久久久久久精品免费看SSS| 国产国产成人久久精品| 久久男人Av资源网站无码软件| 久久久久久久国产免费看| 久久综合噜噜激激的五月天| 精品国产热久久久福利| 国产精品一久久香蕉产线看| 手机看片久久高清国产日韩| 国产福利电影一区二区三区久久久久成人精品综合 | 久久久久久一区国产精品| 国产精品99精品久久免费| 国产精品亚洲综合久久| 久久国产成人| 国产午夜精品理论片久久| 国产精品九九九久久九九| 色欲久久久天天天综合网| 香蕉久久夜色精品国产2020| 中文字幕久久欲求不满| 国产精品视频久久| 91精品国产高清91久久久久久| 亚洲日本va中文字幕久久| 久久久久久久久久久精品尤物| 色婷婷久久久SWAG精品| 久久久久亚洲精品无码网址 | 色播久久人人爽人人爽人人片aV| 国产成人久久久精品二区三区| 亚洲国产天堂久久综合网站| 久久香蕉国产线看观看99| 日韩一区二区久久久久久| 久久99毛片免费观看不卡|