字母表;及查詢提示分析

紫鳳發表於2013-08-28

今日面試題:字母表

每一種語言,都有自己的字母表,類似英文的a-z,但是順序不相同。例如,有的語言可能是z是第一個之類的。現在給定這個語言的字典,請分析這個字典,得到這個語言的字母表的順序。 例如:有如下的字母:

1. C
2. CAC
3. CB
4. BCC
5. BA

經過分析,得到字母表為C->B->A。

===============================================

查詢提示分析

原題

搜尋引擎的查詢提示(suggestion)是非常重要的一個功能。現在給定查詢列表,以及每一個查詢對應的頻率。請設計一種查詢提示的實現方案,要兼顧效果和速度。如果有其他更好的優化點,請給出詳細說明。

分析

這個功能,在搜尋引擎裡是非常常用的。使用者在逐個輸入每一個查詢詞的時候,給出查詢的提示,使用者可以選擇,完成查詢的輸入。這個過程,查詢的提示必須要快。要不然,使用者都輸入完了,還沒有提示,體驗太差。那這個問題要怎麼做呢?

給定的查詢日誌是這樣的:
query1 num1
query2 num2
query3 num3
…
queryn numn

具體的query可能是“薛蠻子”“郭敬明”等等。使用者輸入時,會有哪些狀態呢?

薛
薛蠻
薛蠻子

當使用者輸入完“薛”的時候,就要提示以“薛”開頭的哪些查詢,而且是查詢頻率最高的10個,一般是10個。這裡是考慮總的查詢的頻率最高的10個,在實際的過程中,可以考慮當前熱門的查詢,可能總的次數比較少,但是近幾天使用者差得非常多,這樣的查詢也一定要能夠提示。

形式與目的我們都清楚了。具體做法也是比較多的,最直接的,容易想到trie樹,因為上面列出的幾種狀態,就是字首。那一棵字首樹,顯然是最合適的。我們在這裡,就不詳細說明trie的結構,只給出如何應用trie樹。trie樹的構建:

對於所有查詢,構建trie樹,並且,對於查詢結束的節點,進行標記,儲存查詢的頻率。
由葉子節點開始向上,比如,葉子節點A,父節點為B,B儲存top10的查詢,包括:所有葉子節點代表的查詢,以及,如果B是查詢結束節點,也包括B節點,按照頻率排序的10個查詢。依次向上處理,父節點的top10,是所有子節點的top10合併而成。

這樣查詢的時候,直接是對trie進行查詢,到某一個節點,讀取這個節點儲存的top10查詢即可,同時,這棵樹,對於更新非常友好,可以新增頻率,從葉子節點,回溯到根節點,即可。

或者,採用trie樹,不再節點儲存top10查詢,查詢讀取到可能類表之後再進行查詢,這樣會慢一些,但是記憶體開銷稍微小一些。但,總的來說,trie樹的記憶體開銷是非常大的。那麼,我們看下面的方法。

一般,參與過搜尋引擎的開發過程的,尤其是檢索部分的同學,這個題目,第一個想法,可能不是trie樹,而是倒排結構。總的來講,應用倒排結構,有如下特點,也是和trie樹進行對比:

查詢快
方便壓縮,節省記憶體
更新不方便,可以採用定期重建

具體倒排的做法:

對於每一個查詢的所有字首,做為倒排的索引項,建立倒排
每一個倒排,只儲存top10頻率的查詢

除了上面介紹的之外,還需要考慮拼音等,思路大體相同。只不過更加需要注意記憶體的消耗。

【分析完畢】

本文來自微信:待字閨中,2013-08-26釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。

相關文章