[英]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。
如果性能非常重要,那么您也可以查看全文索引
文章中有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;
}
基本上有兩個優化要考慮
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.