激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - java利用DFA算法實現(xiàn)敏感詞過濾功能

java利用DFA算法實現(xiàn)敏感詞過濾功能

2020-11-22 22:39AlanLee Java教程

在最近的開發(fā)中遇到了敏感詞過濾,便去網(wǎng)上查閱了很多敏感詞過濾的資料,在這里也和大家分享一下自己的理解。下面這篇文章主要給大家介紹了關(guān)于java利用DFA算法實現(xiàn)敏感詞過濾功能的相關(guān)資料,需要的朋友可以參考借鑒,下

前言

敏感詞過濾應(yīng)該是不用給大家過多的解釋吧?講白了就是你在項目中輸入某些字(比如輸入xxoo相關(guān)的文字時)時要能檢

測出來,很多項目中都會有一個敏感詞管理模塊,在敏感詞管理模塊中你可以加入敏感詞,然后根據(jù)加入的敏感詞去過濾輸

入內(nèi)容中的敏感詞并進(jìn)行相應(yīng)的處理,要么提示,要么高亮顯示,要么直接替換成其它的文字或者符號代替。

敏感詞過濾的做法有很多,我簡單描述我現(xiàn)在理解的幾種:

①查詢數(shù)據(jù)庫當(dāng)中的敏感詞,循環(huán)每一個敏感詞,然后去輸入的文本中從頭到尾搜索一遍,看是否存在此敏感詞,有則做相

應(yīng)的處理,這種方式講白了就是找到一個處理一個。

優(yōu)點:so easy。用java代碼實現(xiàn)基本沒什么難度。

缺點:這效率讓我心中奔過十萬匹草泥馬,而且匹配的是不是有些蛋疼,如果是英文時你會發(fā)現(xiàn)一個很無語的事情,比如英文

a是敏感詞,那我如果是一篇英文文檔,那程序它妹的得處理多少次敏感詞?誰能告訴我?

②傳說中的DFA算法(有窮自動機),也正是我要給大家分享的,畢竟感覺比較通用,算法的原理希望大家能夠自己去網(wǎng)上查查

資料,這里就不詳細(xì)說明了。

優(yōu)點:至少比上面那sb效率高點。

缺點:對于學(xué)過算法的應(yīng)該不難,對于沒學(xué)過算法的用起來也不難,就是理解起來有點gg疼,匹配效率也不高,比較耗費內(nèi)存,

敏感詞越多,內(nèi)存占用的就越大。

③第三種在這里要特別說明一下,那就是你自己去寫一個算法吧,或者在現(xiàn)有的算法的基礎(chǔ)上去優(yōu)化,這也是追求的至高境界之一。

那么,傳說中的DFA算法是怎么實現(xiàn)的呢?

第一步:敏感詞庫初始化(將敏感詞用DFA算法的原理封裝到敏感詞庫中,敏感詞庫采用HashMap保存),代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.cfwx.rox.web.sysmgr.util;
 
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import com.cfwx.rox.web.common.model.entity.SensitiveWord;
 
/**
 * 敏感詞庫初始化
 *
 * @author AlanLee
 *
 */
public class SensitiveWordInit
{
  /**
   * 敏感詞庫
   */
  public HashMap sensitiveWordMap;
 
  /**
   * 初始化敏感詞
   *
   * @return
   */
  public Map initKeyWord(List<SensitiveWord> sensitiveWords)
  {
    try
    {
      // 從敏感詞集合對象中取出敏感詞并封裝到Set集合中
      Set<String> keyWordSet = new HashSet<String>();
      for (SensitiveWord s : sensitiveWords)
      {
        keyWordSet.add(s.getContent().trim());
      }
      // 將敏感詞庫加入到HashMap中
      addSensitiveWordToHashMap(keyWordSet);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return sensitiveWordMap;
  }
 
  /**
   * 封裝敏感詞庫
   *
   * @param keyWordSet
   */
  @SuppressWarnings("rawtypes")
  private void addSensitiveWordToHashMap(Set<String> keyWordSet)
  {
    // 初始化HashMap對象并控制容器的大小
    sensitiveWordMap = new HashMap(keyWordSet.size());
    // 敏感詞
    String key = null;
    // 用來按照相應(yīng)的格式保存敏感詞庫數(shù)據(jù)
    Map nowMap = null;
    // 用來輔助構(gòu)建敏感詞庫
    Map<String, String> newWorMap = null;
    // 使用一個迭代器來循環(huán)敏感詞集合
    Iterator<String> iterator = keyWordSet.iterator();
    while (iterator.hasNext())
    {
      key = iterator.next();
      // 等于敏感詞庫,HashMap對象在內(nèi)存中占用的是同一個地址,所以此nowMap對象的變化,sensitiveWordMap對象也會跟著改變
      nowMap = sensitiveWordMap;
      for (int i = 0; i < key.length(); i++)
      {
        // 截取敏感詞當(dāng)中的字,在敏感詞庫中字為HashMap對象的Key鍵值
        char keyChar = key.charAt(i);
 
        // 判斷這個字是否存在于敏感詞庫中
        Object wordMap = nowMap.get(keyChar);
        if (wordMap != null)
        {
          nowMap = (Map) wordMap;
        }
        else
        {
          newWorMap = new HashMap<String, String>();
          newWorMap.put("isEnd", "0");
          nowMap.put(keyChar, newWorMap);
          nowMap = newWorMap;
        }
 
        // 如果該字是當(dāng)前敏感詞的最后一個字,則標(biāo)識為結(jié)尾字
        if (i == key.length() - 1)
        {
          nowMap.put("isEnd", "1");
        }
        System.out.println("封裝敏感詞庫過程:"+sensitiveWordMap);
      }
      System.out.println("查看敏感詞庫數(shù)據(jù):" + sensitiveWordMap);
    }
  }
}

第二步:寫一個敏感詞過濾工具類,里面可以寫上自己需要的方法,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package com.cfwx.rox.web.sysmgr.util;
 
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
 
/**
 * 敏感詞過濾工具類
 *
 * @author AlanLee
 *
 */
public class SensitivewordEngine
{
  /**
   * 敏感詞庫
   */
  public static Map sensitiveWordMap = null;
 
  /**
   * 只過濾最小敏感詞
   */
  public static int minMatchTYpe = 1;
 
  /**
   * 過濾所有敏感詞
   */
  public static int maxMatchType = 2;
 
  /**
   * 敏感詞庫敏感詞數(shù)量
   *
   * @return
   */
  public static int getWordSize()
  {
    if (SensitivewordEngine.sensitiveWordMap == null)
    {
      return 0;
    }
    return SensitivewordEngine.sensitiveWordMap.size();
  }
 
  /**
   * 是否包含敏感詞
   *
   * @param txt
   * @param matchType
   * @return
   */
  public static boolean isContaintSensitiveWord(String txt, int matchType)
  {
    boolean flag = false;
    for (int i = 0; i < txt.length(); i++)
    {
      int matchFlag = checkSensitiveWord(txt, i, matchType);
      if (matchFlag > 0)
      {
        flag = true;
      }
    }
    return flag;
  }
 
  /**
   * 獲取敏感詞內(nèi)容
   *
   * @param txt
   * @param matchType
   * @return 敏感詞內(nèi)容
   */
  public static Set<String> getSensitiveWord(String txt, int matchType)
  {
    Set<String> sensitiveWordList = new HashSet<String>();
 
    for (int i = 0; i < txt.length(); i++)
    {
      int length = checkSensitiveWord(txt, i, matchType);
      if (length > 0)
      {
        // 將檢測出的敏感詞保存到集合中
        sensitiveWordList.add(txt.substring(i, i + length));
        i = i + length - 1;
      }
    }
 
    return sensitiveWordList;
  }
 
  /**
   * 替換敏感詞
   *
   * @param txt
   * @param matchType
   * @param replaceChar
   * @return
   */
  public static String replaceSensitiveWord(String txt, int matchType, String replaceChar)
  {
    String resultTxt = txt;
    Set<String> set = getSensitiveWord(txt, matchType);
    Iterator<String> iterator = set.iterator();
    String word = null;
    String replaceString = null;
    while (iterator.hasNext())
    {
      word = iterator.next();
      replaceString = getReplaceChars(replaceChar, word.length());
      resultTxt = resultTxt.replaceAll(word, replaceString);
    }
 
    return resultTxt;
  }
 
  /**
   * 替換敏感詞內(nèi)容
   *
   * @param replaceChar
   * @param length
   * @return
   */
  private static String getReplaceChars(String replaceChar, int length)
  {
    String resultReplace = replaceChar;
    for (int i = 1; i < length; i++)
    {
      resultReplace += replaceChar;
    }
 
    return resultReplace;
  }
 
  /**
   * 檢查敏感詞數(shù)量
   *
   * @param txt
   * @param beginIndex
   * @param matchType
   * @return
   */
  public static int checkSensitiveWord(String txt, int beginIndex, int matchType)
  {
    boolean flag = false;
    // 記錄敏感詞數(shù)量
    int matchFlag = 0;
    char word = 0;
    Map nowMap = SensitivewordEngine.sensitiveWordMap;
    for (int i = beginIndex; i < txt.length(); i++)
    {
      word = txt.charAt(i);
      // 判斷該字是否存在于敏感詞庫中
      nowMap = (Map) nowMap.get(word);
      if (nowMap != null)
      {
        matchFlag++;
        // 判斷是否是敏感詞的結(jié)尾字,如果是結(jié)尾字則判斷是否繼續(xù)檢測
        if ("1".equals(nowMap.get("isEnd")))
        {
          flag = true;
          // 判斷過濾類型,如果是小過濾則跳出循環(huán),否則繼續(xù)循環(huán)
          if (SensitivewordEngine.minMatchTYpe == matchType)
          {
            break;
          }
        }
      }
      else
      {
        break;
      }
    }
    if (!flag)
    {
      matchFlag = 0;
    }
    return matchFlag;
  }
 
}

第三步:一切都準(zhǔn)備就緒,當(dāng)然是查詢好數(shù)據(jù)庫當(dāng)中的敏感詞,并且開始過濾咯,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@SuppressWarnings("rawtypes")
  @Override
  public Set<String> sensitiveWordFiltering(String text)
  {
    // 初始化敏感詞庫對象
    SensitiveWordInit sensitiveWordInit = new SensitiveWordInit();
    // 從數(shù)據(jù)庫中獲取敏感詞對象集合(調(diào)用的方法來自Dao層,此方法是service層的實現(xiàn)類)
    List<SensitiveWord> sensitiveWords = sensitiveWordDao.getSensitiveWordListAll();
    // 構(gòu)建敏感詞庫
    Map sensitiveWordMap = sensitiveWordInit.initKeyWord(sensitiveWords);
    // 傳入SensitivewordEngine類中的敏感詞庫
    SensitivewordEngine.sensitiveWordMap = sensitiveWordMap;
    // 得到敏感詞有哪些,傳入2表示獲取所有敏感詞
    Set<String> set = SensitivewordEngine.getSensitiveWord(text, 2);
    return set;
  }

最后一步:在Controller層寫一個方法給前端請求,前端獲取到需要的數(shù)據(jù)并進(jìn)行相應(yīng)的處理,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
   * 敏感詞過濾
   *
   * @param text
   * @return
   */
  @RequestMapping(value = "/word/filter")
  @ResponseBody
  public RespVo sensitiveWordFiltering(String text)
  {
    RespVo respVo = new RespVo();
    try
    {
      Set<String> set = sensitiveWordService.sensitiveWordFiltering(text);
      respVo.setResult(set);
    }
    catch (Exception e)
    {
      throw new RoxException("過濾敏感詞出錯,請聯(lián)系維護(hù)人員");
    }
 
    return respVo;
  }

總結(jié)

以上就是這篇文章的全部內(nèi)容了,代碼中寫了不少的注釋,大家可以動動自己的腦筋好好的理解一下。希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:http://www.cnblogs.com/AlanLee/p/5329555.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲国产馆 | 国产色视频免费 | 正在播放91 | 极品五月天 | 在火车上摸两乳爽的大叫 | 高清久久久久 | 99re热视频这里只精品 | 欧美成人免费看 | 欧美成人一级 | 91精品老司机 | 日韩一级毛毛片 | 中文字幕在线观看亚洲 | 国产精品午夜一区 | 日本中文字幕久久 | 色玖玖综合 | 国产免费一区二区三区 | 中日韩乱码一二新区 | 国产免费v片 | 成人性视频免费网站下载软件 | 无遮挡一级毛片视频 | 久久免费综合视频 | 龙的两根好大拔不出去h | 99精品国产在热久久婷婷 | 欧美黄色一区 | 黄污污网站 | 国产羞羞视频在线观看免费应用 | 国产成人av在线播放 | 欧美成人aaaaaaaa免费 | 一区二区免费 | 日韩精品hd | 91美女视频在线观看 | 久久久av亚洲男天堂 | 午夜色视频在线观看 | 中文字幕免费一区 | 免费在线看a | 一区二区久久精品66国产精品 | 综合网天天色 | 国产一国产精品一级毛片 | 一级全毛片 | 亚洲小视频在线观看,com | 久久逼网|