【C++】算法集锦(11):敏感词过滤算法(DFA)
文章目錄
- 什么是 確定的、有窮狀態、機
- 跟我一起看個栗子
- DFA圖解
- DFA示例實現代碼
DFA:確定的 有窮 狀態機
如果 設計模式 中的狀態模式比較熟的話,這個就很清楚了。
DFA常用于敏感詞過濾。
什么是 確定的、有窮狀態、機
啊,看這個名字,就通俗易懂了嘛。首先它是個機,干嘛用的機我說一下:模式串篩選用的機。
常用于從復雜的字符串中篩選有效信息,可以是敏感詞啊、詞法編輯(編譯器使用)等方面。
當然,這是常用,別人這么用。
它這個功能特性啊,我很喜歡。確定、有窮狀態,能想到什么?圖,流程圖!
再細想,什么流程圖?動態流程圖,是吧,很自然吧。
普通流程圖那流程都鎖死了,按部就班就好了,但是動態流程就不一樣了,可能有的人不知道什么叫動態流程圖,不知道正常,我剛起的名字。動態聯編知道吧,就那意思。
我覺得,DFA的機制很適合用于動態流程圖的實現,特別是復雜的,動態流程圖。當然,動態流程圖是可以暴力硬寫的,就是代碼肥了點而已。
跟我一起看個栗子
這也是我最初接觸到DFA的栗子,當時我就是暴力硬寫,當然,代碼肥的我都沒臉貼當時那篇博客里去。
請你來實現一個 atoi 函數,使其能將字符串轉換成整數。
首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符為止。接下來的轉化規則如下:如果第一個非空字符為正或者負號時,則將該符號與之后面盡可能多的連續數字字符組合起來,形成一個有符號整數。 假如第一個非空字符是數字,則直接將其與之后連續的數字字符組合起來,形成一個整數。 該字符串在有效的整數部分之后也可能會存在多余的字符,那么這些字符可以被忽略,它們對函數不應該造成影響。 注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串為空或字符串僅包含空白字符時,則你的函數不需要進行轉換,即無法進行有效轉換。在任何情況下,若函數不能進行有效的轉換時,請返回 0 。提示:
本題中的空白字符只包括空格字符 ’ ’ 。 假設我們的環境只能存儲 32 位大小的有符號整數,那么其數值范圍為 [?231, 231 ? 1]。 如果數值超過這個范圍,請返回 INT_MAX (231 ? 1) 或 INT_MIN (?231) 。 示例 1:輸入: “42” 輸出: 42 示例 2:輸入: " -42" 輸出: -42 解釋: 第一個非空白字符為 ‘-’, 它是一個負號。 我們盡可能將負號與后面所有連續出現的數字組合起來,最后得到 -42 。 示例 3:輸入: “4193 with words” 輸出: 4193 解釋: 轉換截止于數字 ‘3’ ,因為它的下一個字符不為數字。 示例 4:輸入: “words and 987” 輸出: 0 解釋: 第一個非空字符是 ‘w’, 但它不是數字或正、負號。 因此無法執行有效的轉換。 示例 5:輸入: “-91283472332” 輸出: -2147483648 解釋: 數字 “-91283472332” 超過 32 位有符號整數范圍。 因此返回 INT_MIN (?231) 。來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/string-to-integer-atoi
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
DFA圖解
我們的程序在每個時刻有一個狀態 s,每次從序列中輸入一個字符 c,并根據字符 c 轉移到下一個狀態 s’。這樣,我們只需要建立一個覆蓋所有情況的從 s 與 c 映射到 s’ 的表格即可解決題目中的問題。
上面這個圖是不是看不太懂,沒關系,我也看不懂。
但是下面這個表那得看懂:
是吧,第一欄是輸入,第一列是狀態。其他部分就是特定狀態下,遇到特定輸入,會觸發什么狀態。
這個表嘛,當狀態為in_number的時候意味著可以計數了,為signed的時候意味著是符號,為end的時候就意味著該收拾收拾走了。
那,該怎么把這個表轉換為代碼呢?
DFA示例實現代碼
#include<iostream>#include<vector>using namespace std;int DFA(vector<char>& cvec) {vector<vector<int>> vec = { {0,1,2,3},{3,3,2,3},{3,3,2,3},{3,3,3,3} }; //DFAint stat = 0;//實時狀態,初始化為0int ret = 0; //數據紀錄,姑且初始化為0吧int flag = 1;//正負號紀錄for (int sz = 0; sz < cvec.size(); sz++){ //這里是狀態機走一圈if (isspace(cvec[sz]))stat = vec[stat][0];else if (cvec[sz] == '+' || cvec[sz] == '-')stat = vec[stat][1];else if (isdigit(cvec[sz]))stat = vec[stat][2];elsestat = 3;//狀態機走完該判斷狀態了if (stat == 3)return ret * flag;else if (stat == 1) //這個最多也就一次機會進了{if (cvec[sz] == '-')flag = -1;}else if (stat == 2) {}//對數據進行疊加處理,這邊建議先放到數組里,等返回的時候(stat == 3)一次性處理} }總結
以上是生活随笔為你收集整理的【C++】算法集锦(11):敏感词过滤算法(DFA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2019编译 当前最新版chromi
- 下一篇: 精美xp壁纸