• <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.¢% 閱讀(803) 評論(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麻豆图片| 久久人人爽人人爽人人片AV不| 国产精品中文久久久久久久| 麻豆久久| 欧美久久精品一级c片片| 色综合久久久久综合99| 97久久久久人妻精品专区| 亚洲v国产v天堂a无码久久| 国产午夜福利精品久久2021| 国产福利电影一区二区三区久久老子无码午夜伦不| 狠狠色伊人久久精品综合网| 久久久国产精品亚洲一区| 久久影院午夜理论片无码| 久久se精品一区精品二区| 国产成人久久精品一区二区三区 | 久久精品国产一区二区三区| 久久国产精品免费一区二区三区| 久久无码人妻一区二区三区| 久久WWW免费人成—看片| www.久久精品| 精品人妻久久久久久888| 一本久久a久久精品亚洲| 亚洲第一永久AV网站久久精品男人的天堂AV | 久久伊人五月丁香狠狠色| 国产精品日韩欧美久久综合| 亚洲国产另类久久久精品黑人| 91精品国产91久久| 无码人妻久久一区二区三区免费丨| 亚洲伊人久久综合影院| 久久99免费视频| 久久夜色tv网站| 久久国产高清字幕中文| 久久久久国产一级毛片高清版| 亚洲狠狠久久综合一区77777| 久久久青草青青亚洲国产免观 | 中文字幕久久波多野结衣av|