簡體   English   中英

如何有效地檢查給定的字符串是否包含數組中的單詞

[英]How to efficiently check if a given string contains words from an array

我正在構建一個用戶在其中輸入文本塊的應用程序。 提交后,我需要檢查該文本塊是否包含預定義單詞列表中的單詞。
單詞列表很大,大約是50K,所以我需要找出一種可以高效,快速地進行檢查的方法。
這是我已經想過的一些解決方案,但是它們似乎效率很低

選項1:在App的代碼中創建一個功能,該功能僅循環遍歷每個預定義的單詞並檢查該單詞是否在文本塊中

例如

var wordList = ['fox','dog','tree'];  //in my app this list will be large
function contains(userInput) {
    for(i in wordList){
        if(userInput.indexOf(wordList[i]) > -1)
            return true;       
    }
    return false
}

選項2:文本和單詞列表塊都將存儲在數據庫中,因此我可以執行這樣的SQL語句

例如

SELECT *
FROM UserInput ui
    INNER JOIN WordList wl ON wl.word LIKE CONCAT('%', ui.InputText, '%')

有一個更好的方法嗎?

如果您要查看的數據大於小型數據集(可以驗證50k),那么我肯定會在數據庫中進行任何數據處理。

您是正確的,開放式LIKE性能不會很差,但是它比在數據庫外部執行時要快幾個數量級。 如果保證您的用戶輸入是完整單詞,那么您可以將WordList中的所有內容WordList為單獨的單詞,然后進行精確匹配搜索。 如果不能保證從UserInput獲得完整的單詞,那么我將使用您的選項2。

如果性能非常重要,那么您也可以查看全文索引

Aho–Corasick字符串匹配算法

文章中有C#實現的鏈接。

您可以在數據庫中或使用LINQ進行此操作。

在空格上分割用戶輸入,以便您有一個包含用戶輸入字的數組或表值參數。 然后對您的單詞列表進行內部聯接。 聯接之后剩下的所有內容都是在兩個地方都存在的單詞。 性能將非常出色。

SELECT SomeColumn
FROM WordList wl
JOIN @tvp ui ON wl.SomeColumn = ui.SomeColumn

它比進行LIKE搜索要快幾個數量級,並且比全文本索引要容易得多。

我肯定會在應用程序端這樣做。但是我將列表假定為“壞詞”列表,並且它不會經常更改..如果假設是正確的,那么代碼將類似於這個

static List<String> Chached;
List<String> GetBadWords()
{
    if(Chached==null)
    {
         //load words from db into static array
         Chached.Sort();//!important step
    }
    return Chached
}

public bool IstextValid(String sText)
{
    List<String> oBadWords = GetBadWords()
    foreach(String sWord in Rexex.Split(sText,@"\W"))//split by anything not alphanumeric
        if(oBadWords.BinarySearch(sWord )>=0)//since is sorted we can do binary search O(log n)
            return false;
    return true;
}

基本上有兩個優化要考慮

  • 將列表保存在內存中,無需不斷對SQL進行操作
  • 使用二進制搜索來避免O(N * M)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM