• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            排序比較函數:<符號你重載對么了么?

            Posted on 2011-10-15 08:00 S.l.e!ep.¢% 閱讀(801) 評論(0)  編輯 收藏 引用 所屬分類: C++
            前段時間整理臺歷的邏輯數據時考慮到需要去兼容已發布的照片書數據,很多地方做了兼容處理,比如下面這個例子:

            ????? 在很多時候,我們常常會使用map儲存一些需要經常查詢數據結構,而map的key在一開始設計的時候往往不多加思索,很容易就認為它就是個純ID,比如一個數字,或者一個字符串。當隨著產品變得復雜,或者不同數據結構的添加,這個假設往往不堪一擊—-比如在網游中的游戲ID竟然被認為是唯一的Key,而實際上如果涉及到服務器合并,這個ID也就不那么唯一了。很顯然需要解決這個問題就是擴充原來的Key:要么還是將附加信息直接和原先的Key合并,要么將它倆合并到一個數據結構中—-而后者會引來一個小問題:

            ?????? 如果我把這個Key儲存在某個有序容器中,我就需要重新告訴他各個key是按照什么順序排序的。

            ????? 在做照片書的時候,服務器告訴你:哦,我們的模板ID就是唯一標識了,你拿這個ID就可以得到我這邊關于這個作品的所有數據。而到了做臺歷的時候,服務器換了種說法:不好意思,為了充分利用資源,我們很多臺歷用得是同一個模板,你還要告訴我這個臺歷的產品ID。于是shit就這么發生了。

            ?????? 可憐的Key就從string templateID,變成了struct TemplateKey{string m_sTemplateID;string m_sProductID};嗯,這不是什么問題,比較煩的就是如果你用map來儲存,那你就得自己重寫排序比較函數,于是你有了如下的代碼:

            1booloperator<(constTemplateSearchKey &searchKey) const
            2{
            3????????returnm_sProductID < searchKey.m_sProductID &&
            4???????????????m_sTemplateID < searchKey.m_sTemplateID;
            5}

            可惜的是這樣的代碼大錯特錯,試試下面的代碼

            01#include <iostream>
            02#include <map>
            03#include <string>
            04??
            05usingnamespacestd;
            06??
            07structTemplateSearchKey
            08{
            09????string m_sProductID;
            10????string m_sTemplateID;
            11????TemplateSearchKey(conststring& sTemplateID,conststring& sProductID)
            12????{
            13????????m_sTemplateID??? = sTemplateID;
            14????????m_sProductID??? = sProductID;
            15????}
            16??
            17????booloperator<(constTemplateSearchKey &searchKey) const
            18????{
            19????????returnm_sProductID < searchKey.m_sProductID &&
            20???????????????m_sTemplateID < searchKey.m_sTemplateID;
            21????}
            22};
            23??
            24intmain()
            25{
            26????map<TemplateSearchKey,string> testMap;
            27????TemplateSearchKey key("","2");
            28????TemplateSearchKey key1("","1");
            29????TemplateSearchKey key2("","3");
            30????testMap[key] = "a";
            31????testMap[key1] = "b";
            32????testMap[key2] = "c";
            33????cout<<testMap[key]<<endl;
            34????system("pause");
            35????return0;
            36??
            37}

            做調整:

            1booloperator<(constTemplateSearchKey &searchKey) const
            2{
            3??
            4???????returnm_sProductID < searchKey.m_sProductID ||
            5??????????????m_sTemplateID < searchKey.m_sTemplateID;
            6??
            7}

            ?

            而這個連編譯都是不通過的……出一個ASSERT告訴你你的<符號是無效的。

            01template<class_Pr, class_Ty1, class_Ty2> inline
            02bool__CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, const_Ty1& _Left, const_Ty2& _Right,
            03??
            04????constwchar_t*_Where, unsigned int_Line)
            05??
            06{??? // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
            07??
            08if(!_Pred(_Left, _Right))
            09??
            10????return(false);
            11??
            12elseif(_Pred(_Right, _Left))
            13??
            14????_DEBUG_ERROR2("invalid operator<", _Where, _Line); //ASSERT出來的點
            15??
            16return(true);
            17??
            18}

            于是趕緊琢磨了下,改了:

            01booloperator<(constTemplateSearchKey &searchKey) const
            02{
            03??
            04????if(m_sProductID == searchKey.m_sProductID)
            05????{
            06????????returnm_sTemplateID < searchKey.m_sTemplateID;
            07????}
            08????else
            09????{
            10????????returnm_sProductID < searchKey.m_sProductID;
            11????}
            12};

            OK,編譯通過,運行沒問題。可問題也來了,如果有3個成員呢?4個5個呢?一個比較好的方法就是直接把每個成員hash成一個數值,然后各個數值鏈起來,通過比較最后這個值來確定大小。于是就想了,為啥不學JAVA直接把排序功能切成兩部分—-兩個函數hasCode和equals,一個用來確定東西怎么排序,而另外一個用來確定是不是同一個東西。而STL這種做法雖然簡練卻晦澀,需要用戶自己去考慮我寫完的排序函數是不是符合傳說中的排序三定律(有時候即使符合也不能完全反應用戶原意)。

            久久精品国产一区二区| 草草久久久无码国产专区| 久久久久亚洲精品男人的天堂| 夜夜亚洲天天久久| 中文字幕无码久久人妻| 欧洲人妻丰满av无码久久不卡| 成人妇女免费播放久久久| 久久无码AV中文出轨人妻| 亚洲精品乱码久久久久久按摩| 精品久久久久久久| 午夜精品久久久久久影视777| 色婷婷综合久久久中文字幕| 国产成人久久精品麻豆一区 | 久久久久久久久久久久久久| 日韩AV无码久久一区二区| 久久无码一区二区三区少妇 | 亚洲国产精品成人久久| 国产999精品久久久久久| 久久综合亚洲欧美成人| 少妇久久久久久被弄到高潮| 99久久人妻无码精品系列蜜桃| 亚洲欧美国产精品专区久久| 久久被窝电影亚洲爽爽爽| 久久国产亚洲高清观看| 久久精品青青草原伊人| 久久综合精品国产一区二区三区 | 狠狠色丁香久久婷婷综| 久久AV高潮AV无码AV| 综合久久一区二区三区| 无码精品久久一区二区三区| 美女写真久久影院| 伊人色综合久久| 久久99精品国产麻豆宅宅| 香蕉久久av一区二区三区| 色悠久久久久久久综合网| 国产巨作麻豆欧美亚洲综合久久 | 久久久精品2019免费观看| 少妇人妻综合久久中文字幕| 女人高潮久久久叫人喷水| 中文字幕人妻色偷偷久久| 亚洲精品高清国产一线久久|