欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang實(shí)現(xiàn)DFA算法對(duì)敏感詞過(guò)濾功能

 更新時(shí)間:2023年10月09日 08:57:59   作者:paterl  
DFA算法是確定性有限自動(dòng)機(jī),其特征是,有一個(gè)有限狀態(tài)集合和一些從一個(gè)狀態(tài)通向另一個(gè)狀態(tài)的邊,每條邊上標(biāo)記有一個(gè)符號(hào),通俗的講DFA算法就是把你要匹配的做成一顆字典樹(shù),然后對(duì)你輸入的內(nèi)容進(jìn)行匹配的過(guò)程,本文將利用DFA算法實(shí)現(xiàn)敏感詞過(guò)濾,需要的可以參考一下

什么是DFA算法

DFA全稱(chēng):Deterministic Finite Automaton,翻譯過(guò)來(lái)就是確定性有限自動(dòng)機(jī),其特征是,有一個(gè)有限狀態(tài)集合和一些從一個(gè)狀態(tài)通向另一個(gè)狀態(tài)的邊,每條邊上標(biāo)記有一個(gè)符號(hào),其中一個(gè)狀態(tài)是初態(tài),某些狀態(tài)是終態(tài),但是確定性有窮自動(dòng)機(jī)不會(huì)從同一狀態(tài)觸發(fā)的兩個(gè)邊標(biāo)志由相同的符號(hào)。
通俗的講DFA算法就是把你要匹配的做成一顆字典樹(shù),然后對(duì)你輸入的內(nèi)容進(jìn)行匹配的過(guò)程

如何構(gòu)建這顆字典樹(shù)呢

這是一顆簡(jiǎn)單字典樹(shù)的,我們的第一步就是構(gòu)建出一個(gè)這樣的包含敏感詞的樹(shù)

下面我說(shuō)一下構(gòu)建過(guò)程
每個(gè)節(jié)點(diǎn)的結(jié)構(gòu)

// 定義一個(gè)Node結(jié)構(gòu)體,代表DFA的一個(gè)節(jié)點(diǎn)。
type Node struct {
	End  bool   // End字段表示是否為一個(gè)單詞的結(jié)束。
	Next map[rune]*Node   // Next字段是一個(gè)映射,用于存儲(chǔ)此節(jié)點(diǎn)的所有子節(jié)點(diǎn)。
}
// 定義一個(gè)DFAMatcher結(jié)構(gòu)體,代表一個(gè)完整的DFA。
type DFAMatcher struct {
	replaceChar rune   // replaceChar字段是替換敏感詞的字符。
	root        *Node   // root字段是DFA的根節(jié)點(diǎn)。
}

我們要先創(chuàng)捷出一個(gè)root節(jié)點(diǎn),在root節(jié)點(diǎn)中是不存放數(shù)據(jù)的

//創(chuàng)建出一個(gè)DFA樹(shù)的根節(jié)點(diǎn)實(shí)例
func NewDFAMather() *DFAMatcher {
	return &DFAMatcher{
		root: &Node{
			End: false,
		},
	}
}

在確定完節(jié)點(diǎn)的結(jié)構(gòu)后,我們需要跟據(jù)敏感詞來(lái)構(gòu)建這顆字典樹(shù)

// Build方法用于構(gòu)建DFA,它會(huì)將提供的所有單詞添加到DFA中。
func (d *DFAMatcher) Build(words []string) {
	for _, item := range words { // 遍歷提供的所有單詞。
		d.root.AddWord(item) // 將每一個(gè)單詞添加到DFA的根節(jié)點(diǎn)。
	}
}
// AddWord方法用于向當(dāng)前節(jié)點(diǎn)添加一個(gè)單詞。
// 這個(gè)方法會(huì)遍歷單詞的每一個(gè)字符,并為每一個(gè)字符添加一個(gè)子節(jié)點(diǎn)。
func (n *Node) AddWord(word string) {
	node := n                     // 從當(dāng)前節(jié)點(diǎn)開(kāi)始。
	chars := []rune(word)         // 將字符串轉(zhuǎn)化為rune類(lèi)型的切片,以便處理Unicode字符。
	for index, _ := range chars { // 遍歷單詞的每一個(gè)字符。
		node = node.AddChild(chars[index]) // 遞歸地為每一個(gè)字符添加子節(jié)點(diǎn)。
	}
	node.End = true // 設(shè)置最后一個(gè)節(jié)點(diǎn)為單詞的結(jié)束。
}
// AddChild方法向當(dāng)前節(jié)點(diǎn)添加一個(gè)子節(jié)點(diǎn)。
// 如果子節(jié)點(diǎn)已經(jīng)存在,它將不會(huì)被重復(fù)添加。
func (n *Node) AddChild(c rune) *Node {
	if n.Next == nil { // 如果Next字段為nil,則初始化一個(gè)映射。
		n.Next = make(map[rune]*Node)
	}
	//檢查字符c是否已經(jīng)是當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)。
	if next, ok := n.Next[c]; ok { // 如果ok為true,則字符c已經(jīng)是當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn),直接返回該子節(jié)點(diǎn)。
		return next
	} else { // 否則,創(chuàng)建一個(gè)新的節(jié)點(diǎn),并將其設(shè)置為當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)。
		n.Next[c] = &Node{
			End:  false,
			Next: nil,
		}
		return n.Next[c] // 返回新創(chuàng)建的子節(jié)點(diǎn)。
	}
}

根據(jù)上面的代碼就可一構(gòu)建出一顆包含你傳入的敏感詞的樹(shù),在這顆樹(shù)種根節(jié)點(diǎn)不存放數(shù)據(jù)

過(guò)濾關(guān)鍵詞

下面就是跟據(jù)你傳入的內(nèi)容來(lái)過(guò)濾敏感詞了,你可以把敏感詞替換成其他字符,也可以統(tǒng)計(jì)敏感詞的個(gè)數(shù),這就看你自己需要什么了
下面是代碼實(shí)現(xiàn)

// Match方法用于在文本中查找并替換敏感詞。
// 它返回找到的敏感詞列表和替換后的文本。
func (d *DFAMatcher) Match(text string) (sensitiveWords []string, replaceText string) {
	if d.root == nil { // 如果DFA是空的,直接返回原始文本。
		return nil, text
	}
	textChars := []rune(text)                     // 將文本轉(zhuǎn)化為rune類(lèi)型的切片,以便處理Unicode字符。
	textCharsCopy := make([]rune, len(textChars)) // 創(chuàng)建一個(gè)文本字符的副本,用于替換敏感詞。
	copy(textCharsCopy, textChars)                // 復(fù)制原始文本字符到副本。
	length := len(textChars)                      // 獲取文本的長(zhǎng)度。
	for i := 0; i < length; i++ {                 // 遍歷文本的每一個(gè)字符。
	// 在DFA樹(shù)中查找當(dāng)前字符對(duì)應(yīng)的子節(jié)點(diǎn)
		temp := d.root.FindChild(textChars[i])
		if temp == nil {
			continue // 如果不存在匹配,繼續(xù)檢查下一個(gè)字符
		}
		j := i + 1
		// 遍歷文本中的字符,查找匹配的敏感詞,第一個(gè)匹配上了,就進(jìn)行后面的向下匹配
		for ; j < length && temp != nil; j++ {
			if temp.End {
				// 如果找到一個(gè)敏感詞,將其添加到結(jié)果列表中,并在副本中替換為指定字符
				sensitiveWords = append(sensitiveWords, string(textChars[i:j]))
				replaceRune(textCharsCopy, '*', i, j) //替換敏感詞
			}
			temp = temp.FindChild(textChars[j])
		}
		// 處理文本末尾的情況,如果末尾是一個(gè)完整的敏感詞,添加到結(jié)果列表中,并在副本中替換為指定字符
		if j == length && temp != nil && temp.End {
			sensitiveWords = append(sensitiveWords, string(textChars[i:length]))
			replaceRune(textCharsCopy, '*', i, length)
		}
	}
	return sensitiveWords, string(textCharsCopy) // 返回匹配到的敏感詞列表和替換后的文本
}
// FindChild方法用于在當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)中查找一個(gè)特定的子節(jié)點(diǎn)。
func (n *Node) FindChild(c rune) *Node {
	if n.Next == nil { // 如果Next字段為nil,則直接返回nil。
		return nil
	}
	//檢查字符c是否是當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)。
	if _, ok := n.Next[c]; ok { // 如果ok為true,則字符c是當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn),返回該子節(jié)點(diǎn)。
		return n.Next[c]
	}
	return nil // 否則,返回nil。
}
//替換掉文章中出現(xiàn)的關(guān)鍵詞
func replaceRune(chars []rune, replaceChar rune, begin int, end int) {
	for i := begin; i < end; i++ {
		chars[i] = replaceChar
	}
}

以上就是使用Golang代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的DFA算法過(guò)濾敏感詞的一個(gè)算法,這個(gè)算法相對(duì)于其他的性能更好,匹配更快。

到此這篇關(guān)于Golang實(shí)現(xiàn)DFA算法對(duì)敏感詞過(guò)濾功能的文章就介紹到這了,更多相關(guān)Golang敏感詞過(guò)濾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語(yǔ)言簡(jiǎn)介和環(huán)境配置

    Go語(yǔ)言簡(jiǎn)介和環(huán)境配置

    Go語(yǔ)言保證了既能到達(dá)靜態(tài)編譯語(yǔ)言的安全和性能,又達(dá)到了動(dòng)態(tài)語(yǔ)言開(kāi)發(fā)速度和易維護(hù)性,有人形容Go語(yǔ)言:Go=?C?+?Python?,?說(shuō)明Go語(yǔ)言既有C靜態(tài)語(yǔ)言程序的運(yùn)行速度,又能達(dá)到Python動(dòng)態(tài)語(yǔ)言的快速開(kāi)發(fā),這篇文章主要介紹了Go介紹和環(huán)境配置,需要的朋友可以參考下
    2022-07-07
  • Go中變量命名規(guī)則與實(shí)例

    Go中變量命名規(guī)則與實(shí)例

    命名規(guī)則涉及變量、常量、全局函數(shù)、結(jié)構(gòu)、接口、方法等的命名,下面這篇文章主要給大家介紹了關(guān)于Go中變量命名的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • Go語(yǔ)言輸出函數(shù)使用詳解

    Go語(yǔ)言輸出函數(shù)使用詳解

    這篇文章主要介紹了Go語(yǔ)言輸出函數(shù)使用詳解的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • Go單元測(cè)試工具gomonkey的使用

    Go單元測(cè)試工具gomonkey的使用

    本文主要介紹了Go單元測(cè)試工具gomonkey的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 深入了解Go語(yǔ)言中的作用域和變量重聲明

    深入了解Go語(yǔ)言中的作用域和變量重聲明

    在?Go?語(yǔ)言中,代碼塊的嵌套和作用域是程序設(shè)計(jì)的關(guān)鍵概念之一,本文將探討如何在?Go?語(yǔ)言中利用代碼塊的嵌套和作用域來(lái)組織代碼,并介紹變量重聲明的規(guī)則,感興趣的可以了解下
    2023-11-11
  • Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究

    Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究

    這篇文章主要為大家介紹了Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go語(yǔ)言使用defer+recover解決panic導(dǎo)致程序崩潰的問(wèn)題

    Go語(yǔ)言使用defer+recover解決panic導(dǎo)致程序崩潰的問(wèn)題

    如果協(xié)程出現(xiàn)了panic,就會(huì)造成程序的崩潰,這時(shí)可以在goroutine中使用recover來(lái)捕獲panic,進(jìn)行處理,本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-09-09
  • golang讀取yaml配置文件的方法實(shí)現(xiàn)

    golang讀取yaml配置文件的方法實(shí)現(xiàn)

    本文主要介紹了golang讀取yaml配置文件的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Go語(yǔ)言Elasticsearch數(shù)據(jù)清理工具思路詳解

    Go語(yǔ)言Elasticsearch數(shù)據(jù)清理工具思路詳解

    這篇文章主要介紹了Go語(yǔ)言Elasticsearch數(shù)據(jù)清理工具思路詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • Golang實(shí)現(xiàn)拓?fù)渑判?DFS算法版)

    Golang實(shí)現(xiàn)拓?fù)渑判?DFS算法版)

    這篇文章主要介紹了Golang實(shí)現(xiàn)拓?fù)渑判?DFS算法版),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論