【阿里筆試】阿里媽媽關鍵詞熱度排行 (PHP版)
阿新 • • 發佈:2019-01-10
阿里不招PHP!
阿里不招PHP!
阿里不招PHP!
重要的事情說三遍。。。
看到室友在做一個阿里巴巴一個筆試題,只能用C/C++,JAVA,Clang,Clang++什麼的,沒有Python和PHP,感覺有點懵逼。
題目大致是這樣的:
阿里媽媽有個關鍵詞列表,每行記錄由 “關鍵詞+空格+熱度值“ 組成,如 ”連衣裙 96“,現在商家給商品新增一個關鍵詞,要求在商家輸入這個關鍵詞後,顯示類關鍵詞的熱度排行,由高到低。
題目還有定義,什麼是類關鍵詞?即組成漢字完全一樣,順序不一樣,即”連衣裙“和”裙連衣“是類關鍵詞關係,和”長裙“就不是類關鍵詞關係
輸入:一個關鍵詞熱度列表,商家關鍵詞,所有的漢字使用GBK編碼
輸出:類關鍵詞熱度排行
思路很簡單,奈何java和C已經還給老師了,只能php寫一波。
思路 :將關聯詞列表沒個元素分割成關鍵詞和熱度值,作為陣列A的兩個元素。對關鍵詞的每個漢字取其編碼的十進位制值,按照數值大小降序拼接為字串K,對K取其MD5摘要值,作為一個新陣列的的Key,A作為該陣列的一個子陣列。對於Key相同的陣列都放到一個同一個陣列單元,最終將所有的Key對於的數組合併為一個數組D(合併之前需要對每個Key對應的子陣列按照熱度進行二位陣列排序),則該陣列即為查詢字典。商家輸入關鍵詞後,我們計算該關鍵詞的Key,再去D中按Key去子陣列即可。
以上只是我個人的思路,目光短淺,只看到了實現方式,沒有深入思考演算法的優化,如果有不恰當的地方,歡迎大佬們批評指正
_(:з」∠)_
廢話就不多說了,看程式碼:
<?php class Test{ public static function run() { $list = [ '連衣裙 19', '連裙衣 97', '裙連衣 28', '衣裙連 14', '可樂口可 34', '可口可樂 74', '小米手機 78', '小手米機 98', '小米機手 63', '阿里巴巴 47', '阿巴里巴 71', '巴阿巴里 71', ]; $key = '連衣裙'; $re = $this->similarityKeys($list, $key); print_r(json_encode($re)); } /**獲取相似關鍵詞的熱度排序 * @param $list * @param $key * @return array|mixed */ private function similarityKeys($list,$key) { $encoding = 'GBK'; $dictionary = $this->preProcessor($list,$encoding); print_r($dictionary); $key = $this->getKeyMd5String($key,$encoding); if(key_exists($key,$dictionary)) return $dictionary[$key]; else return []; } /**關鍵詞列表預處理 * @param $list * @param $encoding * @return array */ private function preProcessor($list,$encoding) { $data = []; //將key的dec降序排列組成的字串的MD5值相同的項放到一個數組內 foreach ($list as $item) { $re = explode(' ',$item);//分割出關鍵字key 和他的熱度值hot $hash_key = $this->getKeyMd5String($re[0],$encoding); $data[$hash_key][] = $re;//將該記錄加入陣列中 } foreach ($data as $k=>&$v)//對每個類關鍵詞陣列按照熱度值倒序排列 $v = $this->twoDimensionArraySort($v,1,false,false); return $data; } /**將關鍵詞的每個字轉為十進位制數字,按由大到小順序拼接後取其MD5摘要值 * @param $key * @param $encoding * @return string */ private function getKeyMd5String($key,$encoding) { $len = mb_strlen($key,$encoding); $tmp_keys = []; for ($i=0;$i<$len;$i++) //記錄關鍵字中每個字的hex所對應的十進位制值 array_push($tmp_keys,hexdec(bin2hex(mb_substr($key,$i,1,$encoding)))); arsort($tmp_keys);//陣列按照其value降序 $new_key = ''; foreach ($tmp_keys as $k) $new_key .= '_'.$k; return md5($new_key); } /**二維陣列排序 * @param $data array 輸入陣列 * @param $key string 內部陣列的排序鍵 * @param bool $asc 是否升序 * @param bool $keep_key 是否保留原來的鍵 * @return array */ function twoDimensionArraySort($data,$key,$asc=true,$keep_key=true) { $keys = []; foreach ($data as $k=>$v) { $keys[$k] = $v[$key]; } if($asc) asort($keys); else arsort($keys); $re = []; foreach ($keys as $k=>$v) { if($keep_key) $re[$k] = $data[$k]; else array_push($re,$data[$k]); } unset($data,$keys); return $re; } } Test::run();
處理之後的關鍵詞列表如下所示:
{
"58eed1a48f954e80f259ffd7bdca334c": [
["連裙衣", "97"],
["裙連衣", "28"],
["連衣裙", "19"],
["衣裙連", "14"]
],
"2a47cf89f52470a936ff0ff4567b75e3": [
["可口可樂", "74"],
["可樂口可", "34"]
],
"e1600cc8d3dd627209cb843d82e78b74": [
["小手米機", "98"],
["小米手機", "78"],
["小米機手", "63"]
],
"54cf875aaa8f111aaf12fc2d75cc5948": [
["巴阿巴里", "71"],
["阿巴里巴", "71"],
["阿里巴巴", "47"]
]
}
輸入搜尋關鍵詞”連衣裙“,得到結果:
[
["連裙衣", "97"],
["裙連衣", "28"],
["連衣裙", "19"],
["衣裙連", "14"]
]
GG