• <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>
            posts - 12,  comments - 54,  trackbacks - 0
            寫了個nth_element的函數,覺得比較pp,就貼上來了 -- 注意,跟庫函數那個有點差別

             1 void swap( int& a, int& b )
             2 {
             3   
             4     a ^= b;
             5     b ^= a;
             6     a ^= b;
             7 }
             8 
             9 int partation( int* arr, int low, int high )
            10 {
            11     int ans = low - 1;
            12     for ( int i = low; i < high; ++i )
            13     {
            14         if ( arr[i] < arr[high] )
            15         {
            16             swap( arr[i], arr[++ans] );
            17         }
            18     }
            19     swap( arr[++ans], arr[high] );
            20     return ans;
            21 }
            22 
            23 int nth( int* arr, int low, int high, int index )
            24 {
            25     int mid = partation(arr, low, high);
            26     if ( mid == index ) return arr[mid];
            27     return 
            28         ( mid < index )  ? 
            29         nth(arr, mid+1, high, index) :
            30         nth(arr, low, mid-1, index);
            31 }


            然后呢,在某人的新貼下發現這樣的評論:
            真要命,就怕碰見上來就貼一大堆代碼的。
            有比這還可怕的嗎?——有!貼一大堆代碼還沒注釋!


            不管了,反正只是覺得代碼漂亮,沒有想到要解釋什么
            一段測試代碼如下:

             1 #include <iostream>
             2 #include <iterator>
             3 #include <algorithm>
             4 #include <ctime>
             5 using namespace std;
             6 
             7 int main()
             8 {
             9     const int size = 99;
            10     int arr[size];
            11     for ( int index = 0; index < size; ++index )
            12         arr[index] = index;
            13 
            14     srand( time(0) );
            15 
            16     random_shuffle( arr, arr+size );
            17 
            18     copy( arr, arr+size, ostream_iterator<int>( cout, " " ) );
            19     cout << endl;
            20 
            21     cout << "the 73th element is " << nth( arr, 0, size-173 ) << endl;
            22 
            23     copy( arr, arr+size, ostream_iterator<int>( cout, " " ) );
            24     cout << endl;
            25 
            26     return 0;
            27 }
            28 

            由于當序列有序程度很高時候, 這種算法效率比較差,最好在調用之前把目標序列隨機打亂一下,也就是上式random_shuffle( arr, arr+size );的由來。

            P.S: 感謝xxgamexx
            posted on 2008-11-06 16:47 Wang Feng 閱讀(7079) 評論(32)  編輯 收藏 引用 所屬分類: Numerical C++

            FeedBack:
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2008-11-06 17:38 | Kevin
            有點小意見
            個人不太喜歡得地方就加空格,例如:if ( a == b ) return;
            不過LZ在運算符前后又省掉了空格,例如:arr+size

            比較喜歡這樣寫:
            if (a == b) a = a + b;

            每個人寫代碼的習慣不同,所以LZ別介意啊  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 17:50 | Wang Feng
            copy( arr, arr+size, ostream_iterator<int>( cout, " " ) );
            我覺得這樣寫,看起來容易一點
            因為逗號運算符優先級最低,于是arr+size中的加號在逗號之前;
            我的習慣是先運行的更緊密一些;
            如你比較喜歡的這個
            if (a == b) a = a + b;
            我會寫成
            if (a == b) a = a+b;
            或者
            if (a == b)
            {
            a = a+b;
            }
            或者
            if (a == b)
            ++a;
            或者
            if (a == b)
            {
            ++a;
            }
              回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 18:10 | 空明流轉
            如果不需要處理異常,不需要用戶提示,不需要安全機制,不需要照顧性能,
            那么,
            所有的代碼都可以很優美。  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 18:11 | fish_autumn
            效率有待提高  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 18:12 | Wang Feng
            @空明流轉
            @fish_autumn
            請求指點  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 20:05 | cdy20
            換位 很漂亮

            這樣就行了
            a^=b^=a^=b;  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-06 20:55 | Wang Feng
            @cdy20
            這樣寫的話,用g++編譯后交換失敗;
            用icpc編譯后交換成功,非常奇怪
            可有人給出更多測試?
            我的編譯器:
            $ g++ -v
            Using built-in specs.
            Target: x86_64-unknown-linux-gnu
            Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++,treelang --enable-threads=posix --mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic
            Thread model: posix
            gcc version 4.3.2 (GCC)
            $ icpc -v
            Version 10.1
              回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-07 10:50 | zuhd
            能說說這個函數的作用嗎?
            int partation( int* arr, int low, int high )
            沒看明白  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-07 13:50 | Wang Feng
            @zuhd
            你可以這樣理解:
            1) 找到一個arbitrary value A(這個數值應該是任意的,我圖寫起來利落,直接指定為數組的最后一個元素----比較好的做法是,執行之前,在數組中任意尋找一個元素與數組最后一個元素交換)
            2)一個指針指向數組的第一個元素,往向后掃描,找到第一個大于A的元素,標記為arr[a];
            3)另外一個指針指向數組的最后一個元素,向前掃面,找到第一個小于A的元素arr[b];
            4)交換arr[a] arr[b]
            5)若兩個指針沒有重合,轉到2)
            6)將A與兩個指針重合地點的元素交換
            這樣以來,以A為界,把數組分為兩個部分,前邊部分數值都是不大于A的,后邊的部分的數值都是不小于A的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-08 18:17 | 雷長炎
            這就是堆排序的實現了,一趟排序而已。要完整實現堆排序,需要反復調用該函數了。  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2008-11-09 20:58 | cepvoggg
            void swap( int& a, int& b )
            2 {
            3 if ( a == b ) return;
            4 a ^= b;
            5 b ^= a;
            6 a ^= b;
            7 }
            這個代碼是你自己寫的嗎,這個好像是錯的噢
              回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2008-11-09 21:02 | cepvoggg
            在C語言編程專家里面有說過這個代碼是錯的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2008-11-09 21:31 | feng
            @cepvoggg
            是我自己寫的;
            敢問錯在哪里?
            我手里沒有C語言編程專家這本書,你說的是不是C expert programming?  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-10 09:41 | zuhd
            9 int partation( int* arr, int low, int high )
            10 {
            11 int ans = low - 1;
            12 for ( int i = low; i < high; ++i )
            13 {
            14 if ( arr[i] < arr[high] )
            15 {
            16 swap( arr[i], arr[++ans] );
            17 }
            18 }
            19 swap( arr[++ans], arr[high] );
            20 return ans;
            21 }
            ==========================================
            覺得你上面這段代碼好奇怪啊,這個函數的目的是“找到第一個比最后一個數大的數"嗎?如果是這樣,我覺得沒有必要這么寫,我想功能可能不只是這些  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-10 13:11 | Wang Feng
            @zuhd
            不是,這段代碼目的是:以A為界,把數組分為兩個部分,前邊部分數值都是不大于A的,后邊的部分的數值都是不小于A的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-11 09:55 | zuhd
            @Wang Feng
            我有個疑問,就是如果僅滿足“以ans為界,把數組分為兩個部分,前邊部分數值都是不大于arr[ans]的,后邊的部分的數值都是不小于arr[ans]的”,程序的運行結果可以有很多種啊,你的給出的結果的依據是什么呢?  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-11 15:34 | 天策魂之音
            @cepvoggg
            請問這個錯在哪里?

            有沒考慮到的狀況還是?  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-11 15:38 | Wang Feng
            @zuhd
            "程序的運行結果可以有很多種啊"里邊的程序是指 partation還是nth?  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-11 15:39 | Wang Feng
            @天策魂之音
            我用隨機數測試過42憶次,沒有出錯過;
            不知道錯誤是什么  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-12 09:35 | zuhd
            @Wang Feng
            我說的是partation這個函數,如果要求程序輸出“以ans為界,把數組分為兩個部分,前邊部分數值都是不大于arr[ans]的,后邊的部分的數值都是不小于arr[ans]的”,那么結果不是唯一的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-12 21:22 | Wang Feng
            @zuhd
            如果arr已經給定不可更改,那么這個結果就是唯一的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-13 09:47 | zuhd
            比如:
            輸入:3,5,7,4,0,1
            我可以得到這樣的數組3,4,0,1,5,7返回4,即在第4個位子的‘5’把數組分為兩部分。同時我也可以返回3,0,1,4,5,7返回3,即在第3個位子的‘4’把數組分為這樣的兩部分。等等
            這樣的返回值都能滿足你的需求啊  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-13 14:56 | Wang Feng
            @zuhd
            3,5,7,4,0,1
            第一次調用partation(arr, 0, 5)是以1為界分的;
            結果數組被排成
            0 1 7 4 3 5
            返回1  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-14 13:05 | zwp
            人各有好,不打擊樓主對代碼形式的追求。
            但就從實際角度來說,好的設計就會帶來賞心悅目的代碼。  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2008-11-14 16:13 | 阿爾法
            樓主的最后一行代碼明顯錯了:
            return
            28 ( mid < index ) ?
            29 nth(arr, mid+1, high, index) : 應該index改為index-mid吧
            30 nth(arr, low, mid-1, index);
              回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2009-01-07 01:23 | guest
            這樣遞歸的話,如果原數組有正序,不用很長,比如1萬,是會溢出的!  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2009-01-08 10:42 | Wang Feng
            @guest
            確實是這樣的,要解決的話也不是很困難,只要partation時候把數組random shuffle一下就可以了:)  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2009-08-15 12:58 | guest
            個人認為partition跟快排中的partition實現同樣的功能,不過LZ這樣寫不容易讓人看明白。
            lZ的應該是從最前面開始找,找到一個比最后一個小的數,則和從0位置開始的數想交換,執行一次后,ans前面是比它小的數后面是比它大的數。

            另外效率是在不敢恭維。尋找最大或最小比較次數太多。  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2009-08-15 16:06 | feng
            @guest
            其實無論從前邊還是后邊開始尋找,都是可以的
            不過重要的是尋找之前把數列打亂一下,以避免在碰到有序數列的時候時間復雜度飆升的尷尬。

            我覺得效率上沒有什么問題了,絕對是 O(n)。   回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼
            2010-12-31 11:21 | pkuoliver
            @feng
            很明顯,時間復雜度不是O(N),最壞情況下時間復雜度是O(N^2),最好時間復雜度是O(N),平均時間復雜度是O(N*logN)。這是個典型的分治算法。  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2011-04-21 22:58 | feng
            是的  回復  更多評論
              
            # re: nth_element ---- 比較優美的代碼[未登錄]
            2011-08-13 15:04 | xxx
            @雷長炎
            是quicksort的一遍實現,不是heapsort。  回復  更多評論
              

            <2009年1月>
            28293031123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            Link List

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品久久久久久影院| 一本一本久久a久久精品综合麻豆| 99久久做夜夜爱天天做精品| 久久久久亚洲AV无码观看| 国产精品99久久久精品无码| 99久久婷婷国产综合亚洲| 亚洲国产天堂久久综合网站| 性欧美大战久久久久久久 | 久久精品国产91久久麻豆自制| 青青草国产精品久久久久| 久久国产精品视频| 欧美午夜精品久久久久免费视| 中文字幕亚洲综合久久2| 欧美精品国产综合久久| 色偷偷888欧美精品久久久| 无码人妻少妇久久中文字幕| 国产精品久久久久久| 国产精品亚洲综合久久| 精品久久久久久国产三级| 国内精品久久人妻互换| 久久久久99这里有精品10 | 久久国产精品一区二区| 精品国产乱码久久久久软件| 久久高清一级毛片| 久久精品国产99国产精偷| 香蕉久久夜色精品升级完成| 亚洲国产综合久久天堂| 国产亚洲精久久久久久无码AV| av午夜福利一片免费看久久 | 久久久精品视频免费观看| 999久久久无码国产精品| 亚洲精品国精品久久99热一| 香蕉aa三级久久毛片| 久久婷婷五月综合成人D啪| 精品久久久无码中文字幕天天 | 99久久精品国内| 久久久精品国产sm调教网站 | 久久偷看各类wc女厕嘘嘘| 久久久久久精品免费免费自慰 | 国产精品gz久久久| 久久综合综合久久97色|