NFA转换为等价的DFA

Posted coder斌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NFA转换为等价的DFA相关的知识,希望对你有一定的参考价值。

NFA转换为等价的DFA

NFA转换为等价的DFA

明天要进行实验报告的答辩,四个实验,我选择的一个实验报告关于:NFA转换为等价的DFA。实验报告上面的代码,第一眼看得我心里直发麻:What the hell is this?

哎,那就自己写一个吧!

  • 运行环境NodeJS

  • 目录结构

image-20210617220500498

  • 代码展示

  • 注意:因为我在敲代码的时候,没有 ε这个符号,我就用 -代替了,这不影响结果

  • conversionArc.js

    function moveIAndNum(graph, arrList, edge) {
        const moveList = [];
        for (let i = 0; i < arrList.length; i++) {
            const currentEdgs = graph.dictonary.get(arrList[i]);
            for (index in currentEdgs) {
                if (currentEdgs[index] === edge) {
                    moveList.push(index)
                }
            }
        }
        return moveList
    }
    
    module.exports = {
        moveIAndNum
    }
    
  • numClosure.js

     function getNumClosure(graph, num) {
         const newArr = [];
         for (let i = 0; i < num.length; i++) {
             newArr.push(num[i]);
             getNextNum(graph, num[i], newArr);
         }
         return newArr
     }
     // 递归求解 状态集合I- 闭包
     function getNextNum(graph, num, arrList) {
         const startNode = graph.getEdges(num);
         for (item in startNode) {
             if (startNode[item] === '-') {
                 arrList.push(item);
                 getNextNum(graph, item, arrList)
             }
         }
     }
    
     module.exports = {
         getNumClosure
     }
    
    
  • subsetConstruction.js

    const {
        getNumClosure
    } = require('./numClosure');
    const {
        moveIAndNum
    } = require('./conversionArc')
    const {
        getListExiste
    } = require('../utils/utils')
    
    
    // 构造子集
    function getSubsetConst(graph, startNum, constantList) {
        const subsetList = []; // 存放一个个子集
        const startList = [startNum];
        const startSubset = getNumClosure(graph, startList);
        subsetList.push(startSubset);
        for (let flag = 0; flag < subsetList.length; flag++) {
            for (let i = 0; i < constantList.length; i++) {
                const newList = getNumClosure(graph, moveIAndNum(graph, subsetList[flag], constantList[i]));
                const isExiste = getListExiste(newList, subsetList);
                if (isExiste === -1) {
                    subsetList.push(newList);
                }
            }
        }
        const resultList = []; // 存放子集对应的结果
        for (let j = 0; j < subsetList.length; j++) {
            for (let i = 0; i < constantList.length; i++) {
                const newList = getNumClosure(graph, moveIAndNum(graph, subsetList[j], constantList[i]));
                const isExiste = getListExiste(newList, subsetList);
                if (isExiste !== -1) {
                    const tempObj = {};
                    tempObj.from = j;
                    tempObj.route = constantList[i];
                    tempObj.to = isExiste;
                    resultList.push(tempObj);
                }
            }
        }
        return resultList;
    }
    
    module.exports = {
        getSubsetConst
    }
    
    
  • utils.js

    // 比较两个数组内容是否全等
    function compareTwoList(list1, list2) {
        const listlength1 = list1.length;
        const listlength2 = list2.length;
        if (listlength1 != listlength2) {
            return false
        }
        for (let i = 0; i < listlength1; i++) {
            let flag = false;
            for (let j = 0; j < listlength2; j++) {
                if (list1[i] === list2[j]) {
                    flag = true;
                }
            }
            if (!flag) {
                return false
            }
        }
        return true
    }
    // 一个数在另一个数组里面是否存在
    function getListExiste(decimalArray, largeArray) {
        for (let i = 0; i < largeArray.length; i++) {
            const flag = compareTwoList(decimalArray, largeArray[i]);
            if (flag) {
                return i
            }
        }
        return -1
    
    }
    
    module.exports = {
        getListExiste
    }
    
  • main.js入口 js 文件

    const graph = require('./test/data');
    
    const {
        getSubsetConst
    } = require('./controller/subsetConstruction');
    const constantList = ['a', 'b'];
    
    
    console.log(getSubsetConst(graph, '0', constantList));
    
  • Graph.jsDictonary.js分别在这里JavaScript数据结构(图)JavaScript数据结构(字典)

Graph.js我没有完全和上面一致,在 addVertex(val)set时我第二个参数传过去的是一个对象。

  • 测试:

    image-20210617222336766

结果

image-20210617222421904

总结

在写代码的过程中,在求子集和对应的DFA时,我是把两步骤混为了一步,在求子集的同时,想要得到构造DFA后的结果,并没有想到有些NFA转DFA的的关系获取不到! 最后分开求,一下子结果就出来了。

以上是关于NFA转换为等价的DFA的主要内容,如果未能解决你的问题,请参考以下文章

NFA的确定化

利用子集构造法实现NFA到DFA的转换

将字符集转换为 nfa/dfa 的高效算法

C语言实现NFA转DFA

NFA 到 DFA 转换的简明描述?

DFA确定化和最小化