如何高效的從大量關鍵字中選擇N個不同的關鍵字


問題描述:

假設有Sum=10億個關鍵字,以文件形式存儲,一行一個關鍵字。

其中有重復的。共大約有K=1億個不同關鍵字。

現在要求從這里  隨機選取 N個不同的關鍵字。

注意:隨機選取要考慮 關鍵字的頻數

     N可能很小也可能很大

請設計一個 盡量高效的算法

------------------------------------------------------------------------

當前思路:

N如果較小,就按一般方式處理

N如果較大,可能需要判斷 當前選擇的關鍵字是否已經被選擇,如果被選擇過了,則需重選。這個過程的復雜度 太大

所以要盡量避免,選擇到重復的關鍵字。 直接思路是每次選擇 一個關鍵字后 就將其從被選 關鍵字集里剔除。但這里必須保證每個關鍵字被選中的概率不變。

比如 有如下關鍵字和對應頻數

A 2

B 1

C 1

D 1

在從這里選擇兩個關鍵字的前提下,A被選中的概率是:2/5*1+3/5*2/4=21/30 以此類推

如果每個關鍵字只出現一次的話,就相對容易些,維持一個線性表,在邏輯上將這個線性表看成兩部分,

前面部分是待選關鍵字集,后面是已選關鍵字集。每次隨機選擇一個關鍵字后,就把它和后面的數據交換一下。更改rand范圍即可。

但是這里每個關鍵字出現的次數是不一樣的。rand的設計不再那么簡單

總體上有那么幾個想法

1.保留重復判斷

1.1利用折半查找進行快速定位與判斷

對已選擇的關鍵字集進行折半插入排序,每次選擇了一個關鍵字后,用折半查找進行定位與判斷。

折半插入排序代價是O(N2),每次插入一個新的關鍵字

折半查找代價是O(logN)。所以時間復雜度是O(N2)

空間復雜度O(N)

1.2利用hash進行快速判斷

有點類似與數據庫cache中,頁面是否已在cache里的判斷。引入hash,鏈表等。

假設hash使用mod(N)實現

空間復雜度是O(N)

時間復雜度是O(N)

1.3保留重復判斷的一個重要問題

保留重復判斷有一個非常嚴重的問題,假設N逼近關鍵字種類數。

越到后面,隨機選擇到新的關鍵字的概率越小,需要重復隨機選擇的次數越多。

故上述方法一般適用N<<K的情況。當N->K/2時,考慮取消重復判斷,即需要構造隨機選擇

2.取消重復判斷

難點在於隨機選擇的構造,也許這個構造本身的代價也是很大的。

我想了很久,要即可行效率又不能比前面的差。

我的想法是先計算出每個關鍵字被選到的概率。

還是前面的例子A 21/30 B 1/10 C 1/10 D 1/10

rand=rand(0,sum)sum初始為1

然后麻煩的就是建立rand和i(關鍵字序號)之間的關系,這個查找過程消耗的代價也很大。

因為每次選完一個后,都要剔除,所以使用累計概率是不妥的。只能一個個比對過去,邊計算累計概率,邊比對。

概率的計算復雜度目前還沒數

后面選擇的復雜度應該是O(N)的。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM