(8421.BCD碼)加權組合應用

來源:互聯網
上載者:User
1.分析背景: 在實際開發中碰到的一個問題。(會員等級:白金,金,銀,銅) 有一個工作清單,需要根據會員不同身份等級來顯示自己可見的任務(即金牌只能看到金牌可見的任務,自己等級見對應的你的任務)。 一般該怎麼解決呢。 當然是資料庫的任務表上建立一個欄位,標明一下該任務是哪個等級可見不就結了,so easy。 2.疑問: 那麼問題來了,如果我要跨等級顯示呢。即 讓 銅,金可見,銀不可見。即要滿足這四個的各種組合。。。(排3列組合公式 C(n,m)這麼算來著。。哈哈) 3.方法: 方法一:如上邊提到的,建一個新欄位varchar類型,並列的用逗號分隔,儲存哪些等級可見。比如 "金" 或者 "金,銅"。(不方便select) 方法二:建一個int新欄位,使用(8421方法)來加權值區分。
4.分析: 方法一好處是直觀,直接知道哪個等級可見,缺點也顯而易見,我存4個等級豈不是要寫3個逗號分隔,而且這樣是不利於select查詢的啊。方法二隻要建立一個int類型的欄位,裡邊儲存一個1~15兩位元即可(而且訪問量大了int類型的查詢不是更快嘛~~) 那麼,看看方法二是怎麼解決這個問題的。 5.過程 給各個會員等級賦權值如下。 1:銅牌 2:銀牌 4:金牌 8:白金 1.在建立任務insert的時候,比如我設定白金,銅牌可見,按上邊分配,將權值相加 1+8 = 9,資料庫權值欄位 level就存9。 2. 比如我現在是金牌,如何讓我看不到此條資料呢。先查詢出我是金牌對應等級為4,把4傳入下邊函數 toLevelShow(4),返回一個數組,傳回值就是涵蓋了所有金牌可能參與的組合。返回如下:(4,5,6,7,12,13,14,15) 。(4=4,金),(5=1+4 ,銅+金) (6=2+4,銀+金).....很顯然銅+白金=9 不再此傳回值當中。 3. 在select查詢時,select * from table where `level` in ([傳回值]),這樣就查詢出了含有金牌參與的任務了。 6.結論 所以,這個8421權值區分法,本質是統計計算出所有傳入值對應的1248組合情況,然後查詢的時候where in 這些權裡邊就行了。 (那麼,他是如何找出對應等級的排列的呢這是關鍵核心。本質加入了2進位數進一的規律方法,詳細的可以查看研究下函數。) 此套方法不進局限於會員等級吧,所有符合這種組合分情況顯示的情景的都可以使用。
函數如下:    /**     * 輸入(1,2,4,8)其中的一個值,返回其1248所有相加的情況組合     * @param 輸入,(1,2,4,8)任意一個數     * @return 其所有組合相加的結果     * 比如,輸入8,返回array(8,9,10,11,12,13,14,15),     * 因為 8; 8+1=9; 8+2=10; 8+4=12 ; 8+1+2=11 ; 8+1+4=13 ; 8+2+4=14 ; 8+4+2+1=15     * 15是這四個數肯定有的,因為8+4+2+1=15,權值最大     */    function toLevelShow($level_show){        $ret = array();        //把層級轉為二進位        $bin = decbin($level_show);        $len = strlen($bin);        for($i=15;$i>=1;$i--){            $tmp = decbin($i);            $tmp = str_pad($tmp, 4,'0',STR_PAD_LEFT);            $tmp1 = substr($tmp,-$len,1);            if($tmp1==1){                $ret[]=$i;            }        }        return $ret;    }

   /**     * 分拆權值,查看是由(1,2,4,8)這四個數字中那幾個組合而成     * @param 輸入,1-15之間的數,返回1248組合情況。     * @return 1248組成的數組     * 比如,輸入15,返回array(1,2,4,8),因為1+2+4+8 = 15     */    function toLevel($level_show){        $ret = array();        //把層級轉為二進位         $bin = decbin($level_show);        $len = strlen($bin);        for($i=0;$i<$len;$i++){            $tmp = $len-$i;            if($bin[$i]==1){                $dec = bindec(str_pad($bin[$i], $tmp,'0'));                $ret[]=$dec;            }        }        return $ret;    }



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.