java基于Map实现DFA算法

package com.yangkaile.generator;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.*;

/**
 * @description: DFA算法案例
 * @class Name: ApplicationTest
 * @author: wangdong
 * @Date: 2021/7/26 15:56
 */
@Slf4j
public class ApplicationTest {

    @Test
    public void test1(){
        Set<String> keyWordSet=new HashSet<>();
        keyWordSet.add("五连鞭");
        keyWordSet.add("接化发");
        keyWordSet.add("一鞭");
        keyWordSet.add("二鞭");
        keyWordSet.add("三鞭");
        keyWordSet.add("四鞭");
        keyWordSet.add("五鞭");
        keyWordSet.add("混元形意太极掌门人");
        Map dfa_map=addSensitiveWordToHashMap(keyWordSet);
        Set<String> result=getTriggerOverWord("一鞭后直接五鞭,",dfa_map);
        System.out.println(result);
    }
    /**
     * 构建成DFA算法模型
     * @param keyWordSet
     */
    public Map addSensitiveWordToHashMap (Set<String> keyWordSet) {
        Map sensitiveWordMap = new HashMap(keyWordSet.size());     //初始化关键词容器,减少扩容操作
        String key = null;
        Map nowMap = null;
        Map<String, String> newWorMap = null;
        //迭代keyWordSet
        Iterator<String> iterator = keyWordSet.iterator();
        while (iterator.hasNext()) {
            key = iterator.next();    //关键字
            nowMap = sensitiveWordMap;
            for (int i = 0; i < key.length(); i++) {
                char keyChar = key.charAt(i);       //转换成char型
                Object wordMap = nowMap.get(keyChar);       //获取

                if (wordMap != null) {        //如果存在该key,直接赋值
                    nowMap = (Map) wordMap;
                } else {     //不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个
                    newWorMap = new HashMap<String, String>();
                    newWorMap.put("isEnd", "0");     //不是最后一个
                    nowMap.put(keyChar, newWorMap);
                    nowMap = newWorMap;
                }

                if (i == key.length() - 1) {
                    nowMap.put("isEnd", "1");    //最后一个
                }
            }
        }
        return sensitiveWordMap;
    }

    /**
     * 判断从start后的词是否是关键词 -->基于DFA模型判断
     * @param content
     * @param start
     * @return
     */
    public int getOverWordLength(Map keyWordSet,String content,int start,int matchType){
        boolean flag = false;
        int length = 0;
        char word = 0;
        Map nowMap = keyWordSet;
        for (int i = start ; i < content.length() ; i++ ){
            word = content.charAt(i);
            nowMap = (Map) nowMap.get(word);
            if(nowMap == null){
                break;
            }else {
                length++;
                if("1".equals(nowMap.get("isEnd"))){
                    flag = true;
                    if(1 == matchType){
                        break;
                    }
                }
            }
        }
        if (length < 1 || !flag){
            length = 0;
        }
        return length;
    }

    /**
     * 基于DFA模型匹配关键词
     * @param content 待匹配文本
     * @param keyWordSet  关键词
     * @return 返回匹配到的关键词
     */
    public Set<String> getTriggerOverWord(String content,Map keyWordSet){

        Set<String> words = new HashSet<>();

        for (int i = 0 ; i < content.length() ; i++ ){
            int length = getOverWordLength(keyWordSet, content, i,2);
            if(length > 0){
                words.add(content.substring(i,i+length));
                i = i + length - 1;
            }
        }

        return words;
    }
}

Java 程序设计: 一.DFA.javaDFA.java 中的 DFA实现成员函数 boolean recongnizeString(int move[][], int accept_state[], String word),函数功能和参数说明如下。 函数功能:如果 word 被 move 和 accept_state 所代表的 DFA 识别,则返回 true,否 则返回 false. 参数说明: 1) move[][]是状态迁移函数,move 的每一行代表一个状态,每一列代表一个输入符 号,第 0 列代表’a’,第 1 列代表’b’,……,依此类推. 例如:move ={{1,0}, {1,2}, …},则表示此 DFA 在状态 0 时,当输入为’a’时,迁移到状态 1,当输入为’b’ 时迁移到状态 0;而 DFA 在状态 1 时,当输入为’a’时,迁移到状态 1,当输入为’b’ 时迁移到状态 2. 注意:默认状态0是DFA的初始状态. 2) accept_state[]是接受状态的集合,如 accept_state[] = {2, 3},则表示状态 2 和状态 3 是接受状态. 3) word 是待识别的字符串. 注意事项: 1) 字符串 word 的长度在1到50之间. 2) move 的状态数在1到50之间,输入符号数在1到26之间. 3) 只须实现 recognizeString 函数,注意不要修改 DFA.java 文件中其它部分的内容(如 果修改了,请在提交之前改回来),更不要修改 recognizeString 的函数名,参数和 返回类型. 但可以为 DFA 类添加新的成员变量和成员函数. 4) DFA.in 文件是整个程序的输入文件,在本地机器上调试或测试程序时,可以修改 DFA.in 中的内容(用 Editplus 或记事本都可以打开修改),但遵照 DFA.in 的文件格 式. DFA.in 的格式示例如下: 4 2 ----DFA有4个状态,2个输入符号 1 0 ----接下来的 4 行 2 列代表状态迁移函数 1 2 1 3 1 0 3 ----这一行代表接收状态,若有多个用空格隔开 aaabb ----接下来的每行代表一个待识别的字符串 abbab abbaaabb abbb # ----‘#’号代表待识别的字符串到此结束 1 3 ----新的 DFA 开始,格式同上一个 DFA 0 0 0 0 cacba # 0 0 ----两个 0 代表所有输入的结束 5) 当 DFA.in 内容如 4) 时,屏幕应输出 YES NO YES NO YES
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值