[23→100]SKU組合查詢(xún)算法

問(wèn)題場(chǎng)景

SKU最小存貨單位(Stock Keeping Unit)在連鎖零售門(mén)店中有時(shí)稱(chēng)單品為一個(gè)SKU,定義為保存庫(kù)存控制的最小可用單位,例如紡織品中一個(gè)SKU通常表示規(guī)格、顏色、款式。

逛過(guò)淘寶的人都知道一種商品可能有多種屬性類(lèi)型,拿一件衣服來(lái)說(shuō),

  • 性別:男、女
  • 顏色:紅、綠、藍(lán)
  • 尺寸上:38、39、40
  1. 只有3個(gè)屬性全部都選定的時(shí)候,才能真正確定你買(mǎi)的是哪一件衣服,也才能知道衣服對(duì)應(yīng)的價(jià)格、庫(kù)存等信息。

  2. 如果你只選擇了其中1或2個(gè)屬性,剩下未被選擇的屬性要進(jìn)行判斷,確定哪些屬性值可以被選中,哪些不能(因?yàn)橛行﹕ku組合不存在,或者庫(kù)存為0,無(wú)法購(gòu)買(mǎi))

核心問(wèn)題

  1. 如何根據(jù)全部屬性查詢(xún)對(duì)應(yīng)的價(jià)格、庫(kù)存?
  2. 如何確定哪些屬性值可以被選中,哪些不能?

前者很簡(jiǎn)單,遍歷一遍所有的SKU信息列表就知道了,或者利用Map直接獲取就行。后者比較麻煩,需要進(jìn)行多次匹配。大體思想如下:

  1. 遍歷SKU列表,從中選出包含已選中屬性和屬性值的條目列表containTargetList;
  2. 遍歷containTargetList,找出存在其中的未被選中屬性的屬性值
  3. 結(jié)合未被選中屬性的全部屬性值未被選中屬性在containTargetList中存在的屬性值,確定未被選中屬性中哪些屬性值是不能被選中的。

附錄:Python的簡(jiǎn)易實(shí)現(xiàn)版

#!/usr/bin/python
# -*- coding: utf-8 -*-
#################################
## 輸入:連續(xù)點(diǎn)擊事件
## 輸出:各個(gè)按鈕的狀態(tài)
#################################

# 不同的規(guī)格屬性
KEYS = {
"size":["38", "39", "40"],
"color":["red", "blue", "green"],
"sex":["man", "woman"],
};

# 不同的規(guī)格屬性組合對(duì)應(yīng)的 庫(kù)存和價(jià)格
SKUS = {
"39;red;man":{"price":100, "count":10},
"40;red;man":{"price":100, "count":10},
"38;grean;woman":{"price":100, "count":20},
"39;red;woman":{"price":100, "count":30},
"39;blue;man":{"price":100, "count":10},
"40;blue;man":{"price":100, "count":10},
"38;blue;woman":{"price":100, "count":20},
"39;green;woman":{"price":100, "count":30},
}


def processSku(inputData):
    ## 1. 預(yù)處理數(shù)據(jù),將規(guī)格的屬性值變?yōu)閷?duì)象的屬性值,便于讀取比較
    for sku in SKUS:
        array = sku.split(";");
        SKUS[sku]["size"] = array[0]
        SKUS[sku]["color"] = array[1]
        SKUS[sku]["sex"] = array[2]
    ## 2. 找出被選中的屬性值列表
    inputDataArray = inputData.split(";");
    targetedDict = {}
    for data in inputDataArray:
        if ":" in data:
            [key, value] = data.split(":")
            targetedDict[key] = value
    print "已經(jīng)選中的屬性:" , targetedDict
    if(len(targetedDict) == len(KEYS)):
        key = "%s;%s;%s" % (targetedDict["size"],targetedDict["color"],targetedDict["sex"])
        if key in SKUS:
            print "所有屬性皆被選中,對(duì)應(yīng)的結(jié)果為\n" , key , ":", SKUS[key]
        else:
            print "所有屬性皆被選中,但查無(wú)結(jié)果\n"
        return;
    ## 3. 找出未被選中的屬性值列表
    unTargetDict = {}
    for key in KEYS:
        if key not in targetedDict:
            unTargetDict[key] = KEYS[key]
    print "未被選中的屬性:" , unTargetDict
    ## 4. 判斷未被選中的屬性值是否能被選中
    ### 4.1. 遍歷規(guī)格屬性組合,找到包含`targetedDict屬性值`的所有sku組合
    containTargetList = []
    for skuItem in SKUS:
        canAppend = True
        for key in targetedDict:
            if SKUS[skuItem][key] != targetedDict[key]:
                canAppend = False
                break;
        if canAppend:
            containTargetList.append(SKUS[skuItem])
    print "包含選中屬性的sku條目:"
    for skuItem in containTargetList:
        print skuItem

    ### 4.2 判斷每個(gè)屬性下面每個(gè)屬性值的存在狀態(tài),True表示可以選中,F(xiàn)alse表示不能繼續(xù)選擇了
    skuStaus = {}
    for skuKey in unTargetDict:
        skuStaus[skuKey] = {}
        for skuValue in unTargetDict[skuKey]:
            skuStaus[skuKey][skuValue] = False;

    for skuItem in containTargetList:
        for skuKey in unTargetDict:
            for skuValue in unTargetDict[skuKey]:
                if skuItem[skuKey] ==  skuValue:
                    skuStaus[skuKey][skuValue] = True;
                    break;

    print "\n可繼續(xù)選中的屬性值狀態(tài)為: "
    for skuKey in skuStaus:
        print skuKey,":",skuStaus[skuKey]

### 測(cè)試數(shù)據(jù)
inputDatas =[
# "size:39",
"size:40;",
# "size:39;sex:woman", #選中size 39和sex:woman
# "size:39;sex:woman;color:red",
# "size:39;sex:woman;color:red1",
]

for inputData in inputDatas:
    print "\n\n------Start:測(cè)試數(shù)據(jù)為%s------" % inputData
    processSku(inputData)
    print "------end----------------\n\n"

優(yōu)化建議:

  1. 如果用戶(hù)下一次選中的屬性值,沒(méi)有影響之前的屬性值選擇。也就是說(shuō),用戶(hù)上一次選中了“男”這個(gè)屬性值,這一次選中了“40”這個(gè)屬性值,可以直接在上一次containTargetList的基礎(chǔ)上繼續(xù)過(guò)濾,而不用遍歷全部的SKU列表。

Panda

2016-05-19

參考:

  1. Fan同學(xué)提供的算法概要
  2. 淘寶SKU組合查詢(xún)算法實(shí)現(xiàn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,656評(píng)論 19 139
  • 工廠(chǎng)模式類(lèi)似于現(xiàn)實(shí)生活中的工廠(chǎng)可以產(chǎn)生大量相似的商品,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠(chǎng)模式。簡(jiǎn)單...
    舟漁行舟閱讀 8,131評(píng)論 2 17
  • 1、窗體 1、常用屬性 (1)Name屬性:用來(lái)獲取或設(shè)置窗體的名稱(chēng),在應(yīng)用程序中可通過(guò)Name屬性來(lái)引用窗體。 ...
    Moment__格調(diào)閱讀 4,795評(píng)論 0 11
  • 文/狗乖乖 拿秒回來(lái)說(shuō)事的人,一定是個(gè)理想大蝦。 工作和生活中,我是個(gè)比較典型的健忘癥者。每凡遇到開(kāi)會(huì),會(huì)前我都會(huì)...
    薛靜春閱讀 284評(píng)論 10 11
  • 1. 有一次和周其仁教授聊天,我請(qǐng)教他一個(gè)問(wèn)題:這么多年來(lái),經(jīng)??匆?jiàn)您出門(mén)演講,但是從來(lái)不見(jiàn)您上電視,同樣是傳播思...
    雨露姐閱讀 209評(píng)論 0 0

友情鏈接更多精彩內(nèi)容