2014-04-26 46 views
-1

我正在構建一個簡單的天真文本總結算法。該算法是這樣工作的:最有效的方法來創建一個天真的文本總結算法

  • 我的算法的第一步是刪除所有停用詞(stop words in English)。
  • 在我的文本只包含具有實際含義的單詞後,我將查看每個單詞在文本中使用多少次以查找單詞的頻率。例如,如果使用「超級計算機」一詞5次,它將有frequency = 5
  • 然後,我要通過將sum of the frequencies of all words in the sentence除以number of the words in the sentence來計算每個句子的權重。
  • 在最後一步,我將按照它們的長度對句子進行排序。

我需要在C++(如V8模塊的NodeJS)寫這個算法,但問題是,在過去的幾年裏,我一直在用高級腳本語言如Javascript的工作主要是和我不在C++中經驗豐富。在JavaScript中,我可以使用正則表達式來刪除所有停用詞,然後查找頻率,但在C++中似乎要複雜得多。

我想出了以下的想法:

struct words { 
    string word; 
    int freq; 
} 

std::vector<words> Words; 
  • 停止的話會在V8局部數組或std :: vector的預加載。
  • 對於文本中的每個單詞,我要遍歷所有停用詞,如果當前單詞不是停用詞,則檢查它是否在結構中,如果不是 - >將word添加到Words vector,如果存在將頻率增加1.
  • 當我找到所有單詞的所有頻率後,我將再次遍歷文本以找出每個句子的權重。

而且這個主意幾個問題來到我的腦海:

  1. 我的文章將主要1000+的話。對於每個單詞循環100個以上的停用詞將會進行100000次迭代,以找出停用詞。這似乎是無效的。
  2. 當我有了頻率後,我需要再循環一遍文本1000+單詞和300+單詞(在矢量頻率中)來計算每個句子的權重。

我的想法似乎是無效的,但我不熟悉C++。

所以我的問題是有更好的方法來做到這一點或優化我的算法,尤其是我上面列出的問題?

我很擔心我的算法的性能和任何提示/建議將不勝感激。

+1

右邊的蝙蝠,你可以設置一個'unordered_map'來保存停止詞而不是'std :: vector',因此檢查一個詞是否是停用詞是'O(1)',而不是通過循環正如你所說的,100多個停用詞。 – Alejandro

+0

您也可以將找到的單詞存儲在大多數情況下都是O(log n)的[二叉查找樹](http://en.wikipedia.org/wiki/Binary_search_tree)中。 – jmstoker

+0

或者對兩者都使用'unordered_map'。每當你找到一個單詞時,更新它的頻率。這將花費'O(n)'的時間。計算句子的權重就是查找單詞的頻率,這個單詞的頻率是'O(1)','unordered_map','O(n)'是'vector'。 – Alejandro

回答

0

欲瞭解停用詞彙,請查看std::unordered_set。您可以將所有停用字串存儲在std::unordered_set<string>中,然後當您想要比較字符串時,請致電count(string)以查看它是否存在。

對於單詞/頻率對,請在某些評論中使用std::unordered_map。如果您在單個地圖查找中同時執行查找和插入操作,這將是最快的。嘗試是這樣的:

struct Frequency 
{ 
    int val; 
    Frequency() : val(0) {} 
    void increment() 
    { 
     ++val; 
    } 
}; 

std::unordered_map<std::string, Frequency> words; 

void processWord(const std::string str) 
{ 
    words[str].increment(); 
} 

words[str]搜索在地圖上一個字,如果它不存在添加。新單詞將調用頻率的初始化爲零的構造函數。所以你所要做的就是在每個單詞上撥打processWord

相關問題