聽起來像inverted index仍然會對你有用。它是包含它們的文檔的有序列表上的文字地圖。這些文檔需要有一個共同的總體排序,並且它們按照它們出現在每個單詞桶中的順序排列。
假設你n
在字語料庫的總長度出現(而不是詞彙尺寸),可以在時間O(n log n)
和線性空間構成。
鑑於P1
和P2
,您進行了兩個單獨的查詢以分別獲取包含兩個詞的文檔。由於這兩個列表都有一個共同的排序,你可以做一個線性的合併類算法只選擇那些含有P1
文件,但不P2
:
c1 <- cursor to first element of list of docs containing P1
c2 <- cursor to first element of list of docs containing P2
results <- [] # our return value
while c1 not exhausted
if c2 exhausted or *c1 < *c2
results.append(c1++)
else if *c1 == *c2
c1++
c2++
else # *c1 > *c2
c2++
return results
通知循環迭代至少一個光標的每通;它在兩個初始查詢的大小總和中以線性時間運行。由於只有來自c1
光標的東西輸入results
,我們知道所有結果都包含P1
。最後,請注意,我們總是隻提前輸入「滯後」遊標:這個(以及整個文檔排序)可以保證,如果一個文檔出現在兩個初始查詢中,將會有一個循環迭代,其中兩個遊標都指向該文檔。當這種迭代發生時,中間條款必然會啓動並且通過推進兩個遊標來跳過文檔。因此,包含P2
必然的文檔不會將添加到results
。
此查詢是一個稱爲布爾查詢的常規類的示例;可以將此算法擴展到大多數布爾表達式。某些查詢打破了算法的效率(迫使它遍歷整個詞彙空間),但基本上只要你不否定每個詞(即不要求not P1 and not P2
),你就沒問題。請參閱this進行深入處理。
來源
2012-06-20 07:04:41
phs