最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2017年06月21日 10:06:31   作者:AlanLee  
在最近的開發(fā)中遇到了敏感詞過濾,便去網(wǎng)上查閱了很多敏感詞過濾的資料,在這里也和大家分享一下自己的理解。下面這篇文章主要給大家介紹了關(guān)于java利用DFA算法實(shí)現(xiàn)敏感詞過濾功能的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

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

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

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

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

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

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

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

缺點(diǎn):這效率低,而且匹配的是不是有些無語,如果是英文時(shí)你會(huì)發(fā)現(xiàn)一個(gè)很無語的事情,比如英文

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

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

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

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

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

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

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

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

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

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;
    // 使用一個(gè)迭代器來循環(huán)敏感詞集合
    Iterator<String> iterator = keyWordSet.iterator();
    while (iterator.hasNext())
    {
      key = iterator.next();
      // 等于敏感詞庫,HashMap對象在內(nèi)存中占用的是同一個(gè)地址,所以此nowMap對象的變化,sensitiveWordMap對象也會(huì)跟著改變
      nowMap = sensitiveWordMap;
      for (int i = 0; i < key.length(); i++)
      {
        // 截取敏感詞當(dāng)中的字,在敏感詞庫中字為HashMap對象的Key鍵值
        char keyChar = key.charAt(i);

        // 判斷這個(gè)字是否存在于敏感詞庫中
        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)前敏感詞的最后一個(gè)字,則標(biāo)識(shí)為結(jié)尾字
        if (i == key.length() - 1)
        {
          nowMap.put("isEnd", "1");
        }
        System.out.println("封裝敏感詞庫過程:"+sensitiveWordMap);
      }
      System.out.println("查看敏感詞庫數(shù)據(jù):" + sensitiveWordMap);
    }
  }
}

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

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)中的敏感詞,并且開始過濾咯,代碼如下:

@SuppressWarnings("rawtypes")
  @Override
  public Set<String> sensitiveWordFiltering(String text)
  {
    // 初始化敏感詞庫對象
    SensitiveWordInit sensitiveWordInit = new SensitiveWordInit();
    // 從數(shù)據(jù)庫中獲取敏感詞對象集合(調(diào)用的方法來自Dao層,此方法是service層的實(shí)現(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層寫一個(gè)方法給前端請求,前端獲取到需要的數(shù)據(jù)并進(jìn)行相應(yīng)的處理,代碼如下:

/**
   * 敏感詞過濾
   * 
   * @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("過濾敏感詞出錯(cuò),請聯(lián)系維護(hù)人員");
    }

    return respVo;
  }

總結(jié)

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

相關(guān)文章

  • SpringBoot整合token實(shí)現(xiàn)登錄認(rèn)證的示例代碼

    SpringBoot整合token實(shí)現(xiàn)登錄認(rèn)證的示例代碼

    本文主要介紹了SpringBoot整合token實(shí)現(xiàn)登錄認(rèn)證的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • MyBatis-Plus?分頁不生效的解決方法

    MyBatis-Plus?分頁不生效的解決方法

    本文主要介紹了MyBatis-Plus?分頁不生效的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java使用遞歸法解決漢諾塔問題的代碼示例

    Java使用遞歸法解決漢諾塔問題的代碼示例

    這篇文章主要介紹了Java使用遞歸法解決漢諾塔問題的代碼示例,漢諾塔問題是使用遞歸解決問題的經(jīng)典范例,用到的算法非常簡單,需要的朋友可以參考下
    2016-04-04
  • SpringBoot集成JWT令牌詳細(xì)說明

    SpringBoot集成JWT令牌詳細(xì)說明

    這篇文章主要介紹了SpringBoot集成JWT令牌詳細(xì)說明,JWT方式校驗(yàn)方式更加簡單便捷化,無需通過redis緩存,而是直接根據(jù)token取出保存的用戶信息,以及對token可用性校驗(yàn),單點(diǎn)登錄,驗(yàn)證token更為簡單,需要的朋友可以參考下
    2023-10-10
  • java線程池詳解及代碼介紹

    java線程池詳解及代碼介紹

    這篇文章主要介紹了java中線程池的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • 詳解java封裝實(shí)現(xiàn)Excel建表讀寫操作

    詳解java封裝實(shí)現(xiàn)Excel建表讀寫操作

    這篇文章給大家分享了java封裝實(shí)現(xiàn)Excel建表讀寫操作的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2018-08-08
  • IDEA設(shè)置maven修改settings.xml配置文件無法加載倉庫的解決方案

    IDEA設(shè)置maven修改settings.xml配置文件無法加載倉庫的解決方案

    這篇文章主要介紹了IDEA設(shè)置maven修改settings.xml配置文件無法加載倉庫的解決方案,幫助大家更好的利用IDEA進(jìn)行JAVA的開發(fā)學(xué)習(xí),感興趣的朋友可以了解下
    2021-01-01
  • Java中RocketMq的消費(fèi)方式詳解

    Java中RocketMq的消費(fèi)方式詳解

    這篇文章主要介紹了Java中RocketMq的消費(fèi)方式詳解,RocketMQ的消費(fèi)方式都是基于拉模式拉取消息的,而在這其中有一種長輪詢機(jī)制(對普通輪詢的一種優(yōu)化),來平衡上面Push/Pull模型的各自缺點(diǎn),需要的朋友可以參考下
    2023-10-10
  • 淺談Java(SpringBoot)基于zookeeper的分布式鎖實(shí)現(xiàn)

    淺談Java(SpringBoot)基于zookeeper的分布式鎖實(shí)現(xiàn)

    這篇文章主要介紹了Java(SpringBoot)基于zookeeper的分布式鎖實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Android接入微信支付的方法

    Android接入微信支付的方法

    這篇文章主要介紹了Android接入微信支付的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論

吴旗县| 夏邑县| 平南县| 睢宁县| 镇坪县| 康定县| 滁州市| 略阳县| 赞皇县| 绥滨县| 新郑市| 平定县| 沈丘县| 阿克苏市| 织金县| 鲜城| 海城市| 开鲁县| 易门县| 利津县| 红河县| 普兰县| 石景山区| 孟连| 宁安市| 邢台市| 大田县| 十堰市| 齐齐哈尔市| 自治县| 亚东县| 故城县| 秀山| 三亚市| 宁武县| 南宫市| 永福县| 山西省| 峡江县| 禄劝| 靖西县|