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

            99久久久精品| 国产偷久久久精品专区| 奇米影视7777久久精品人人爽| 亚洲国产精品综合久久一线| 久久AV高潮AV无码AV| 99久久er这里只有精品18| a级毛片无码兔费真人久久| 久久久噜噜噜久久| 久久精品视频一| 中文字幕亚洲综合久久2| 四虎国产精品成人免费久久| 久久精品人人做人人妻人人玩| 久久综合久久综合久久| 要久久爱在线免费观看| 久久久精品国产sm调教网站| 久久99精品国产一区二区三区| 国产精品成人99久久久久| 亚洲精品无码久久久久久| 国产精品无码久久综合网| 欧美久久天天综合香蕉伊| 亚洲AV乱码久久精品蜜桃| 久久er国产精品免费观看8| 中文字幕热久久久久久久| 国产 亚洲 欧美 另类 久久| 99久久精品国产一区二区 | 久久久久久a亚洲欧洲aⅴ| 国产成人久久精品一区二区三区| 精品久久久久久无码中文野结衣| 久久ZYZ资源站无码中文动漫| 久久天天躁狠狠躁夜夜avapp| 欧美精品一区二区久久| 99久久99久久精品国产| 国内精品伊人久久久久AV影院| 一级做a爰片久久毛片看看| 久久精品成人一区二区三区| 97久久精品人人澡人人爽| 亚洲一区二区三区日本久久九| 久久大香香蕉国产| 精品午夜久久福利大片| 久久午夜电影网| 99久久国产热无码精品免费久久久久|