[23→100]SKU組合查詢算法

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

SKU最小存貨單位(Stock Keeping Unit)在連鎖零售門店中有時(shí)稱單品為一個(gè)SKU总棵,定義為保存庫(kù)存控制的最小可用單位签杈,例如紡織品中一個(gè)SKU通常表示規(guī)格屠阻、顏色般渡、款式释牺。

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

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

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

核心問(wèn)題

  1. 如何根據(jù)全部屬性查詢對(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. 如果用戶下一次選中的屬性值,沒(méi)有影響之前的屬性值選擇圣絮。也就是說(shuō)祈惶,用戶上一次選中了“男”這個(gè)屬性值,這一次選中了“40”這個(gè)屬性值扮匠,可以直接在上一次containTargetList的基礎(chǔ)上繼續(xù)過(guò)濾捧请,而不用遍歷全部的SKU列表。

Panda

2016-05-19

參考:

  1. Fan同學(xué)提供的算法概要
  2. 淘寶SKU組合查詢算法實(shí)現(xiàn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棒搜,一起剝皮案震驚了整個(gè)濱河市疹蛉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌力麸,老刑警劉巖可款,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件育韩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡筑舅,警方通過(guò)查閱死者的電腦和手機(jī)座慰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)翠拣,“玉大人版仔,你說(shuō)我怎么就攤上這事∥竽梗” “怎么了蛮粮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谜慌。 經(jīng)常有香客問(wèn)我然想,道長(zhǎng),這世上最難降的妖魔是什么欣范? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任变泄,我火速辦了婚禮,結(jié)果婚禮上恼琼,老公的妹妹穿的比我還像新娘妨蛹。我一直安慰自己,他們只是感情好晴竞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布蛙卤。 她就那樣靜靜地躺著,像睡著了一般噩死。 火紅的嫁衣襯著肌膚如雪颤难。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天已维,我揣著相機(jī)與錄音行嗤,去河邊找鬼。 笑死垛耳,一個(gè)胖子當(dāng)著我的面吹牛昂验,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播艾扮,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼既琴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了泡嘴?” 一聲冷哼從身側(cè)響起甫恩,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酌予,沒(méi)想到半個(gè)月后磺箕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奖慌,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年松靡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了简僧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雕欺,死狀恐怖岛马,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屠列,我是刑警寧澤啦逆,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站笛洛,受9級(jí)特大地震影響夏志,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苛让,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一沟蔑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狱杰,春花似錦瘦材、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)九杂。三九已至颁湖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間例隆,已是汗流浹背甥捺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留镀层,地道東北人镰禾。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像唱逢,于是被迫代替她去往敵國(guó)和親吴侦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

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