最近須要給遊戲作一個敏感詞新系統,我採用的方法是比較經常使用的DFA(肯定有窮狀態機)算算法
法,先不講算法,而這種算法的實現須要一個相應的敏感詞庫。編碼
我拿到了詞庫後發現詞庫中大概有8000+個詞,其中包括不少重複的,還有不少有着頭包含關lua
系的詞;spa
什麼是頭包含詞呢? 看以下例子:code
咱們知道在DFA算法讀取敏感詞後若是存在這種狀況:blog
詞1: "ab" 詞2: "abc" 索引
在讀取以後「 ab 「這個敏感詞就會不復存在而被abc覆蓋掉, 而咱們遊戲須要對敏感詞進行的遊戲
操做不是以其餘字符(如 * *)代替句子中的敏感詞而是若是判斷出句子中含有敏感詞,則沒法發ip
出。因此,若是 「ab」 已是敏感詞了,「abc」就沒有必要出如今敏感詞庫中了因此我須要將敏感字符串
詞庫中的
1. 相同的詞只留下一個
2. 刪除頭包含其餘敏感詞的敏感詞
可是現有的敏感詞庫中有8000+ 個詞我不可能一個個去找,因此我就想到了利用現有的lua io
文件庫對原先的敏感詞庫進行處理這樣能夠節省太多的時間 代碼以下
local function getNewWord() local wordsDataInput = {} local wordsDataOutput = {} -- 讀取文件 -- 以只讀方式打開文件 local file_input = io.open("sensitive_words_input.txt", "r") -- 設置默認輸入文件爲 test.lua io.input(file_input) -- 逐行讀取文件 local string_l = file_input:read("*l") while(string_l ~= nil) do table.insert(wordsDataInput, string_l) string_l = file_input:read("*l") end io.close(file_input) -- 寫入文件 -- 以只寫方式打開文件 local file_output = io.open("sensitive_words.txt", "a") -- 設置默認輸出文件爲 io.output(file_output) -- 對數據進行處理 -- 若是有頭包含 local function ifIsHeadInTable(str) for i = 1, #wordsDataInput do local startIndex, endIndex = string.find(wordsDataInput[i], str) if startIndex ~= nil and endIndex ~= nil then -- 若是find到頭索引爲1,尾索引不爲字符串長度則能夠認定爲是頭包含關係 if startIndex == 1 and endIndex ~= string.len(wordsDataInput[i]) then wordsDataInput[i] = "\n" end end end end -- 是否已經有相同的 local function isHasSameInTable(str) if not wordsDataOutput or not next(wordsDataOutput) then return false end for key, value in ipairs(wordsDataOutput) do if value == str then return true end end return false end -- 先剔除頭包含 for key, value in pairs(wordsDataInput) do ifIsHeadInTable(value) end -- 再剔除相同的 for key, value in ipairs(wordsDataInput) do if not isHasSameInTable(value) then table.insert(wordsDataOutput, value) end end for index, word in pairs(wordsDataOutput) do io.write(word.."\n") end io.close(file_output) end
操做後的文件少了整整4000個詞,差很少35kb,這樣加載詞庫須要的空間和時間都大大減小。可是要注意的是lua對文件的操做都是以UTF-8編碼來的,若是是其餘編碼的文件就不能用了。