• <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這種做法雖然簡練卻晦澀,需要用戶自己去考慮我寫完的排序函數是不是符合傳說中的排序三定律(有時候即使符合也不能完全反應用戶原意)。

            segui久久国产精品| 国内精品九九久久精品| 久久免费精品视频| 久久99久久成人免费播放| 四虎影视久久久免费| 日本久久久久亚洲中字幕| 精品国产福利久久久| 久久婷婷是五月综合色狠狠| 久久婷婷色综合一区二区| 精品久久久久久中文字幕| 亚洲&#228;v永久无码精品天堂久久| 7777精品伊人久久久大香线蕉| 日本久久久久亚洲中字幕| 久久精品国产亚洲AV不卡| 97精品伊人久久久大香线蕉| 91精品国产91热久久久久福利| 精品国产乱码久久久久软件| 97精品伊人久久久大香线蕉| 亚洲人成网亚洲欧洲无码久久| 国内精品久久久久久久涩爱 | 精品久久久中文字幕人妻| 青青热久久综合网伊人| 欧美熟妇另类久久久久久不卡| 婷婷久久精品国产| 精品久久国产一区二区三区香蕉| 奇米影视7777久久精品| 精品一二三区久久aaa片| 少妇久久久久久被弄到高潮| 久久噜噜电影你懂的| 久久国产精品99国产精| 久久精品亚洲AV久久久无码| 亚洲AⅤ优女AV综合久久久| 9191精品国产免费久久| 久久―日本道色综合久久| 久久精品aⅴ无码中文字字幕重口| 亚洲伊人久久综合影院| 精品久久久久久国产牛牛app| 品成人欧美大片久久国产欧美...| 大伊人青草狠狠久久| 国产精品久久久久久搜索| 久久综合狠狠色综合伊人|