利用標準庫排序的幾種方法

來源:互聯網
上載者:User

這個題目有點兒無聊,跟茴香豆的“茴”字有幾種寫法一樣無聊,又是一個無聊的老掉牙的話題——排序,問題依然是無聊至極——把輸入的單詞按順序(我可沒說是什麼順序)排列。當作是一個總結吧。

按詞典排好說,如果你用vector<string> words儲存單詞,只需用algorithm裡的sort即可:sort(words.begin(),words.end())。這玩意兒我閉著眼也能敲出來。但假如你用list的話……編譯器發脾氣了吧?(發脾氣是好的,要是沒有任何抱怨,趁早兒扔了吧)。list容器不支援隨機訪問,標準庫的sort沒法用到它上面。幸好list自己帶了一個sort,所以要用words.sort()。

如果要按和詞典相反的順序排呢?對sort而言,預設是採用“<”來比較的,如果讓它採用“大於”不就行了嗎?標準庫當然為此“預留了介面”。你可以先寫一個比較函數,如compare,記著用大於符號“>”比較:

bool compare(string s1, string s2)...{
    return s1>s2;
}

接著調用三個參數的sort版本:sort(words.begin(),words.end(),compare)就成了。對於list容器,這個方法也適用,把compare作為sort的參數就可以了,即:words.sort(compare)。

更進一步,我現在要讓這種操作更加能適應變化。也就是說,我希望能給比較函數一個參數,用來指示是按升序還是按降序排。這回輪到函數對象出場了。

為了描述方便,我先定義一個枚舉類型EnumComp用來表示升序和降序。很簡單:

enum EnumComp...{ASC, DESC};

然後開始用一個類來描述這個函數對象。它會根據它的參數來決定是採用“<”還是“>”。嗯……我想應該是這個樣子的:

class Compare
...{
    private:
        EnumComp comp;
    public:
        Compare(EnumComp c):comp(c)...{};
        bool operator()(string s1, string s2)...{
            switch(comp)...{
                case DESC:
                    return s1>s2;
                case ASC:
                    return s1<s2;
            }
        }
};

好了,想按升序排,那就sort(words.begin(),words.end().Compare(ASC));想按降序排,就sort(words.begin(),words.end(),Compare(DESC))。

其實對於這麼簡單的任務(類型支援“<”、“>”等比較子),完全沒必要自己寫一個類出來。標準庫裡已經有現成的了,就在functional裡,把它include進來就行了。functional提供了一堆基於模板的比較函數對象。它們是(看名字就知道意思了):equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。對於這個問題來說,greater和less就足夠了,直接拿過來用:

  • 升序:sort(words.begin(),words.end(),less<string>());
  • 降序:sort(words.begin(),words.end(),greater<string>()).

上面的幾種方法都還算是“正大光明”,那麼偏方是什嗎?看看sort的參數,前兩個是迭代器……嗯,記不記得有個“反向迭代器”的玩意兒?沒錯,預設的sort會用小於符號比較,如果換成反向迭代器,不就“騙”過sort了嗎?sort(words.rbegin(),words.rend())。

再來考慮一個更難一點兒的問題:按長度遞增的順序排序,長度相同的按字典順序排。這回如果簡單地用兩次sort就不行了,第二次的排序很可能會把前一次的成果完全毀掉。根本原因是大多數的sort都是採用“快速排序”演算法實現的,而快速排序是一種不穩定排序,也就是說,如果兩個元素A和B的值相同,排序前A在B的前面,那麼經過快速排序後,並不能保證A仍然在B的前面。現在需要的是一種“穩定排序”的演算法,它可以保證在排序後相同值的元素的相對位置不變。

稍微想一下可知,應該先按字典順序排,再用穩定排序的方法按長度排。標準庫提供了一個stable_sort,用來實現穩定排序。先來定義一個字串長度的比較函數:

bool length_comp(string s1, string s2)...{
    return s1.size()<s2.size();
}

接著兩行代碼就完成了任務:

 sort(words.begin(),words.end());
 stable_sort(words.begin(),words.end(),length_comp);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.