阿里不招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