この記事はWeChatの公開アカウント「UP Technology Control」から転載したもので、著者はconanです。この記事を転載する場合は、UP Technology Controlの公式アカウントまでご連絡ください。 繊細な単語やテキストのフィルタリングは Web サイトの重要な機能であり、適切で効率的なフィルタリング アルゴリズムを設計することが非常に重要です。 テキスト フィルタリングを実装するためのアルゴリズムの中で、DFA は唯一の比較的優れた実装アルゴリズムです。 DFA は Deterministic Finite Automaton の略で、決定論的有限オートマトンです。イベントと現在の状態から次の状態を取得します。つまり、イベント + 状態 = 次の状態です。センシティブな単語フィルタリングを実装するためのアルゴリズムでは演算を削減する必要がありますが、DFA アルゴリズムでは計算はほとんどなく、状態遷移のみになります。 C#で実装する方法を見てみましょう 1. センシティブワードライブラリクラスを構築する- プライベートブール LoadDictionary()
- {
- var wordList = 新しいリスト<文字列>();
- _memoryLexicon == nullの場合
- {
- _memoryLexicon = 新しいWordGroup[ char .MaxValue];
- var words = new SensitiveWordBll().GetAllWords();
- if ( 単語 == null )
- 戻る 間違い;
- foreach (文字列 word in words)
- {
- wordList.Add (単語) ;
- var chineseWord = Microsoft.VisualBasic.Strings.StrConv(word,
- Microsoft.VisualBasic.VbStrConv.TraditionalChinese、0);
- if (単語 != 中国語単語)
- wordList.Add (中国語の単語) ;
- }
- foreach (var word in wordList)
- {
- (単語の長さ > 0)
- {
- var group = _memoryLexicon[単語[0]];
- if (グループ== null )
- {
- グループ= 新しい WordGroup();
- _memoryLexicon[単語[0]] =グループ;
- }
- グループ.Add (単語.部分文字列( 1));
- }
- }
- }
- 戻る 真実;
- }
2. センシティブな単語検出クラスを構築する- プライベート boolチェック(文字列 blackWord)
- {
- _wordlength = 0;
- //ソースの次のカーソルを検出します
- _nextCursor = _cursor + 1;
- var 見つかりました = false ;
- var 継続チェック = 0;
- //各単語を走査して一致するものを探す
- (var i = 0; i < blackWord.Length; i++)の場合
- {
- //特殊文字オフセットカーソル
- var オフセット = 0;
- _nextCursor >= _sourceText.Length の場合
- {
- (i - 1 < blackWord.Length - 1) の場合
- 見つかりました = false ;
- 壊す;
- }
- それ以外
- {
- // 下の文字が漢字、数字、文字ではないかどうかを確認し、オフセットを1増やします
- (var y = _nextCursor; y < _sourceText.Length; y++)の場合
- {
- if (!IsChs(_sourceText[y]) && !IsNum(_sourceText[y]) && !IsAlphabet(_sourceText[y]))
- {
- オフセット++;
- //特殊文字を避け、下カーソルが文字列の長さ以上の場合はジャンプします
- (_nextCursor + offset >= _sourceText.Length) の場合
- 壊す;
- _単語長++;
- }
- そうでなければ中断します。
- }
- (_nextCursor + offset >= _sourceText.Length) の場合
- {
- 見つかりました = false ;
- 壊す;
- }
- if (blackWord[i] == _sourceText[_nextCursor + offset])
- {
- 見つかりました = true ;
- 継続チェック = 0;
- }
- それ以外
- {
- // 一致するものが見つからない場合は、さらに4文字を一致させようとします
- (continueCheck < 4 && _nextCursor < _sourceText.Length - 1) の場合
- {
- チェックを続行します++;
-
- }
- それ以外
- {
- 見つかりました = false ;
- 壊す;
- }
- }
- }
- _nextCursor = _nextCursor + 1 + オフセット;
- _単語長++;
- }
- 戻り値が見つかりました。
- }
- }
3. テストと使用方法- _illegalWords = 新しいリスト<文字列>();
- if (string.IsNullOrEmpty(sourceText) && string.IsNullOrEmpty(_sourceText))
- {
- ソーステキストを返します。
- }
-
- if (!string.IsNullOrEmpty(sourceText))
- _sourceText = ソーステキスト;
- _カーソル = 0;
- もしも (!LoadDictionary())
- {
- _sourceText を返します。
- }
-
- var tempString = _sourceText.ToCharArray();
- var sourceTextDbc = ToDBC(ソーステキスト);
- (var i = 0; i < SourceText.Length; i++)の場合
- {
- //この単語を最初の文字として含むフレーズをクエリします
- varグループ= _memoryLexicon[sourceTextDbc[i]];
- if (グループ!= null )
- {
- (var z = 0; z <グループ. Count (); z++)の場合
- {
- 文字列 word = group.GetWord (z);
- if (word.Length == 0 || Check (word))
- {
- if (isFirstCheckedReturn)
- {
- 戻る ヌル;
- }
-
- var blackword = 文字列.Empty;
- (var pos = 0; pos < _wordlength + 1; pos++)の場合
- {
- blackword += tempString[pos + _cursor].ToString();
- tempString[pos + _cursor] = ReplaceChar;
- }
- _illegalWords.Add (ブラックワード) ;
-
- _cursor = _cursor + _wordlength;
- i = i + _単語長;
- 壊す;
- }
- }
- }
- _カーソル++;
- }
- 新しい文字列(tempString)を返します。
- var フィルター = 新しい SensitiveWordFilter();
- filter.SourceText = "dddddd" ;
- var ソーステキスト = filter.SourceText;
- フィルターをリセットします。
- var datetime = DateTime.Now;
- var ss = filter.Filter();
- var datetime2 = DateTime.Now;
- var ミリ秒 = (datetime2 - datetime).TotalMilliseconds;
- Console.WriteLine(ミリ秒);
- Console.WriteLine(ss);
- var words = System.IO.File.ReadAllLines(@ "D:\Recv\Sensitive Word Library.txt" , System.Text.Encoding.UTF8);
- var ssx = ソーステキスト;
- var datetimex = DateTime.Now;
- foreach (var word in words)
- {
- (単語の長さ > 0)
- ssx = ssx.Replace (word, "*" .PadLeft(word.Length, '*' ));
- }
- var datetime2x = DateTime.Now;
- var millisecondx = (datetime2x - datetimex).TotalMilliseconds;
- Console.WriteLine(ミリ秒x);
- コンソールに行を書き込む
|