{"id":250,"date":"2013-05-12T09:29:44","date_gmt":"2013-05-12T01:29:44","guid":{"rendered":"http:\/\/blog.dayandcarrot.net\/?p=250"},"modified":"2013-05-12T09:29:44","modified_gmt":"2013-05-12T01:29:44","slug":"%e8%af%8d%e6%b3%95%e5%88%86%e6%9e%90%ef%bc%9a%e5%a6%82%e4%bd%95%e5%b0%86nfa%e8%bd%ac%e6%8d%a2%e4%b8%badfa","status":"publish","type":"post","link":"https:\/\/dayandcarrot.space\/?p=250","title":{"rendered":"\u8bcd\u6cd5\u5206\u6790\uff1a\u5982\u4f55\u5c06NFA\u8f6c\u6362\u4e3aDFA"},"content":{"rendered":"<ul>\n<li>\u672c\u6587\u6765\u6e90\u53ca\u53c2\u8003\u8d44\u6599\uff1a<\/li>\n<\/ul>\n<ol>\n<li>http:\/\/hi.baidu.com\/beanchx\/item\/b153390de0691827a1312d49<\/li>\n<li>http:\/\/www.2cto.com\/kf\/201302\/191521.html<\/li>\n<li>http:\/\/dev.21tx.com\/2009\/09\/26\/11354.html<\/li>\n<\/ol>\n<h2>\u30001. \u5b50\u96c6\u6784\u9020(Subset Construction)<\/h2>\n<p>\u8fd9\u662f\u4e00\u4e2a\u8f6c\u6362NFA\u5230DFA\u7684\u7b97\u6cd5\u3002\u6211\u4eec\u77e5\u9053NFA\u548cDFA\u7684\u533a\u522b\u6700\u4e3b\u8981\u7684\u5c31\u662f\u4e00\u4e2a\u72b6\u6001\u548c\u4e00\u4e2ainput symbol\u662f\u5426\u80fd\u591f\u786e\u5b9a\u4e00\u4e2a\u72b6\u6001\u7684\u95ee\u9898\uff0c\u5bf9\u4e8eNFA\uff0c\u5b83\u5c06\u786e\u5b9a\u4e00\u4e2a\u7ec4\u72b6\u6001\uff0c\u800cDFA\u5c06\u786e\u5b9a\u4e00\u4e2a\u72b6\u6001\uff0c\u56e0\u6b64\uff0c\u6211\u4eec\u6709\u4e00\u4e2a\u5f88\u597d\u7684\u529e\u6cd5\u5c31\u662f\u628aNFA\u7684\u72b6\u6001\u96c6\u5bf9\u5e94\u6bcf\u4e2aDFA\u7684\u72b6\u6001\uff0c\u8fd9\u5c31\u662fsubset construction\u7684\u601d\u60f3\uff0c\u4e0d\u8fc7\u8fd9\u53ea\u662f\u5927\u6982\u6cdb\u6cdb\u800c\u8bba\uff0c\u6211\u4eec\u9700\u8981\u66f4\u52a0\u660e\u786e\u7684\u8ba4\u8bc6<br \/>\n1) NFA\u5728\u4efb\u4f55\u4e00\u4e2ainput symbol\u4e0b\uff0c\u6620\u5c04\u7684\u72b6\u6001\u96c6(\u901a\u8fc7move\u51fd\u6570\uff0c\u8fd9\u4e2a\u96c6\u5408\u901a\u5e38\u7528T\u5b57\u6bcd\u8868\u793a)\u5e94\u8be5\u88ab\u77e5\u9053<br \/>\n2) \u5fc5\u987b\u4fdd\u8bc11)\u4e2d\u72b6\u6001\u96c6\u90fd\u5bf9\u5e94\u4e86DFA\u4e2d\u7684\u4e00\u4e2a\u72b6\u6001<\/p>\n<h2>\u3000\u3000\u5177\u4f53\u7b97\u6cd5\uff1a<\/h2>\n<p>Input : \u4e00\u4e2aNFA N<br \/>\nOutput : \u63a5\u53d7\u76f8\u540c\u8bed\u8a00\u7684DFA D<br \/>\nMethod : \u4e3aD\u6784\u67b6\u4e00\u4e2atransition table(\u8f6c\u6362\u8868) Dtran\uff0c\u6bcf\u4e2aDFA\u7684\u72b6\u6001\u662f\u4e00\u4e2aNFA\u7684\u72b6\u6001\u96c6\u5408(\u8fd9\u91cc\u4e00\u5b9a\u8981\u6ce8\u610f\u524d\u9762\u8bf4\u8fc7\u76841)2)\u4e24\u70b9)\u3002\u6211\u4eec\u5b9a\u4e49\u4e00\u4e9b\u64cd\u4f5c\uff1a<br \/>\ns \u8868\u793aNFA\u7684\u72b6\u6001\uff0cT \u8868\u793aNFA\u7684\u72b6\u6001\u96c6\u5408\uff0ca\u8868\u793a\u4e00\u4e2ainput symbol<br \/>\n\u03b5-transition(\u03b5\u8f6c\u6362)\u5c31\u662f\u8bf4input symbol\u4e3a\u03b5\u65f6\u7684transition(\u8f6c\u6362)<br \/>\n&nbsp;<\/p>\n<table>\n<tbody>\n<tr>\n<td>\u64cd\u4f5c(operation)<br \/>\n&nbsp;<\/td>\n<td>\u63cf\u8ff0(description)<br \/>\n&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>\u03b5-closure(s)<br \/>\n&nbsp;<\/td>\n<td>\u4eceNFA\u7684\u72b6\u6001s\u51fa\u53d1\uff0c\u53ea\u901a\u8fc7\u03b5-transition\u5230\u8fbe\u7684NFA\u7684\u72b6\u6001\u96c6\u5408<br \/>\n&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>\u03b5-closure(T)<br \/>\n&nbsp;<\/td>\n<td>NFA\u7684\u96c6\u5408T\u4e2d\u7684\u72b6\u6001p\uff0c\u53ea\u901a\u8fc7\u03b5-transition\u5230\u8fbe\u7684NFA\u7684\u72b6\u6001\u96c6\u5408\uff0c\u518d\u6c42\u8fd9\u4e9b\u96c6\u5408\u7684\u4ea4\u96c6\u3002\u7528\u6570\u5b66\u8868\u8fbe\u5c31\u662f {p|p \u5c5e\u4e8e \u03b5-closure(t) , t\u5c5e\u4e8eT}<br \/>\n&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>move(T,a)<br \/>\n&nbsp;<\/td>\n<td>NFA\u7684\u96c6\u5408\uff0c\u8fd9\u4e2a\u96c6\u5408\u5728input symbol\u4e3aa\uff0c\u72b6\u6001\u4e3aT\u4e2d\u4efb\u610f\u72b6\u6001\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7\u4e00\u4e2a\u8f6c\u6362\u5f97\u5230\u7684\u96c6\u5408<br \/>\n&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<br \/>\n\u6ce8\u610f\u4e00\u4e0b\uff0c\u6240\u6709\u7684\u64cd\u4f5c\u90fd\u662f\u9488\u5bf9NFA\u7684\u72b6\u6001\u6216\u8005\u72b6\u6001\u96c6\u5408\uff0c\u5f97\u5230\u7684\u65f6NFA\u7684\u72b6\u6001\u96c6\u5408\uff0c\u6216\u8005\u8bf4\u662fDFA\u770b\u4e3a\u4e00\u4e2a\u72b6\u6001<br \/>\nSubset Construction<br \/>\n\u521d\u59cbDstates\uff0c\u5b83\u4ec5\u4ec5\u542b\u6709\u72b6\u6001(D\u7684\u72b6\u6001)\u03b5-closure(s0)\uff0c\u5e76\u4e14\u72b6\u6001\u672a\u88ab\u6807\u8bb0\uff0cs0\u8868\u793a\u5f00\u59cb\u72b6\u6001\uff0c\u6ce8\u610f\uff0cDstates\u653e\u7684\u662fD\u7684\u72b6\u6001<br \/>\n<code>while\u3000(\u3000Dstates\u3000\u6709\u672a\u6807\u8bb0\u7684\u72b6\u6001\u3000T\u3000)\u3000{\u3000\/\/\u3000T\u662fD\u4e2d\u7684\u4e00\u4e2a\u72b6\u6001\uff0c\u4e5f\u662fN\u4e2d\u4e00\u4e2a\u72b6\u6001\u96c6<br \/>\n\u6807\u8bb0\u3000T;<br \/>\nfor\u3000(\u3000input\u3000symbol\u3000a\u3000){\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\/\/\u3000\u904d\u5386\u6240\u6709\u7684input\u3000symbol<br \/>\nU\u3000=\u3000\u03b5-closure(move(T,\u3000a));\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\/\/\u3000move\u4e3aNFA\u7684move\u51fd\u6570<br \/>\nif\u3000(\u3000U\u3000\u4e0d\u5728\u3000Dstates\u3000\u4e2d\u3000)<br \/>\n\u628aU\u4f5c\u4e3a\u5c1a\u672a\u6807\u8bb0\u7684\u72b6\u6001\u52a0\u5165Dstates;<br \/>\nDtran[T,\u3000a]\u3000=\u3000U<br \/>\n}<br \/>\n}<\/code><br \/>\n\u6ce8\u610f\uff0c\u72b6\u6001s\uff0c\u03b5-closure(s)\u4e00\u5b9a\u5305\u542bs<br \/>\n\u6211\u4eec\u5148\u6765\u719f\u6089\u4e0a\u9762\u7684\u64cd\u4f5coperation\uff0c\u518d\u6765\u770b\u4e0a\u9762\u7684\u7b97\u6cd5<br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\u8bcd\u6cd5\u5206\u6790(4)---NFA\u4e0eDFA\u7684\u8f6c\u5316\" src=\"http:\/\/img2.21tx.com\/2009\/09\/26\/13718.jpg\" width=\"516\" height=\"227\" border=\"0\" \/><br \/>\n<code>\u03b5-closure(0)\u3000=\u3000{0,\u30001,\u30002,\u30004,\u30007}\u3000\u3000\u3000\/\/\u3000\u4ece0\u72b6\u6001\u51fa\u53d1\u7684\uff0cinput\u3000symbol\u4e3a\u03b5\u7684\u6240\u6709\u72b6\u6001\u7684\u96c6\u5408<br \/>\n\u03b5-closure(3)\u3000=\u3000{1,\u30002,\u30003,\u30004,\u30006,\u30007}<br \/>\n\u03b5-closure(8)\u3000=\u3000{8}<br \/>\n\u03b5-closure(\u3000{3,\u30008}\u3000)\u3000=\u3000\u03b5-closure(3)\u3000U\u3000\u03b5-closure(8)\u3000=\u3000{1,\u30002,\u30003,\u30004,\u30006,\u30007,\u30008}<br \/>\nmove(0,a)\u3000=\u3000\u7a7a<br \/>\nmove(7,a)\u3000=\u3000{8}<br \/>\nmove(8,b)\u3000=\u3000{9}<br \/>\nmove(\u3000{0,\u30001,\u30002,\u30004,\u30007},\u3000a)\u3000=\u3000move(0,a)\u3000U\u3000move(1,a)\u3000U\u3000move(2,a)\u3000U\u3000move(4,a)\u3000U\u3000move(7,a)\u3000=\u3000{3,\u30008}<\/code><br \/>\n\u73b0\u5728\u53ef\u4ee5\u56de\u53bb\u7406\u89e3\u4e00\u4e0b\u7b97\u6cd5\u4e86\u3002<br \/>\n\u8fd9\u91cc\u518d\u8bf4\u8bf4\u6c42\u03b5-closure(T)\u7684\u7b97\u6cd5\uff1a<br \/>\n<code>\u628aT\u7684\u6240\u6709\u72b6\u6001\u538b\u5165stack(\u6808);<br \/>\n\u03b5-closure(T)\u7684\u521d\u59cb\u503c\u4e3a\u3000T\u3000\u4e2d\u7684\u6240\u6709\u5143\u7d20\u3000;\u3000\u3000\/\/\u3000\u4e5f\u5c31\u662f\u4e00\u5b9a\u5305\u542b\u4ed6\u4eec\u672c\u8eab<br \/>\nwhile(\u3000\u6808\u975e\u7a7a\u3000)\u3000{<br \/>\n\u5f39\u51fa\u6808\u9876\u5143\u7d20\u3000t\u3000;<br \/>\nfor(\u3000\u6bcf\u4e2a\u5c5e\u4e8e\u3000move(t,\u3000\u03b5)\u3000\u7684\u72b6\u6001\u3000u\u3000){<br \/>\nif(\u3000u\u3000\u4e0d\u5728\u3000\u03b5-closure(T)\u3000\u4e2d\u3000){<br \/>\nu\u3000\u52a0\u5165\u3000\u03b5-closure(T);<br \/>\n\u628a\u3000u\u3000\u5165\u6808;<br \/>\n}<br \/>\n}<br \/>\n}<\/code><br \/>\n\u4e0b\u9762\u5bf9\u4e0a\u56fe\u5982\u4f55\u4f7f\u7528Set Construction\u7b97\u6cd5\u6765\u6784\u5efaDFA\u505a\u4e00\u4e2a\u8be6\u7ec6\u7684\u63cf\u8ff0\uff1a<br \/>\n1. \u521d\u59cb\u5316Dstates \u628a\u96c6\u5408 \u03b5-closure(s0) = {0, 1, 2, 4, 7}\u4f5c\u4e3a\u7b2c\u4e00\u4e2a\u72b6\u6001\uff0c\u8bbe\u6b64\u72b6\u6001\u4e3a A<br \/>\n2. \u73b0\u5728\u8f6c\u5316\uff0cinput symbol {a, b}\uff0c\u56e0\u6b64\uff0c\u6c42\uff1a<br \/>\n\u03b5-closure(move(A, a));<br \/>\n\u03b5-closure(move(A, b));<br \/>\n\u8fd9\u91cc\u4f1a\u5f97\u52302\u4e2a\u72b6\u6001<br \/>\n\u03b5-closure(move(A, a)) = {1, 2, 3, 4, 6, 7, 8},\u8bbe\u5176\u4e3a B<br \/>\n\u03b5-closure(move(A, b)) = {1, 2, 4, 5, 6, 7}, \u8bbe\u5176\u4e3aC<br \/>\nB\uff0cC\u653e\u5165Dstates<br \/>\n\u6539\u5199 Dtrans<br \/>\n\u6700\u7ec8\u5f97\u5230\u7684 Dtrans \u4e3a\uff1a<br \/>\nA = {0, 1, 2, 4, 7}<br \/>\nB = {1, 2, 3, 4, 6, 7, 8}<br \/>\nC = {1, 2, 4, 5, 6, 7}<br \/>\nD = {1, 2, 4, 5, 6, 7, 9}<br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\u8bcd\u6cd5\u5206\u6790(4)---NFA\u4e0eDFA\u7684\u8f6c\u5316\" src=\"http:\/\/img2.21tx.com\/2009\/09\/26\/13720.jpg\" width=\"224\" height=\"204\" border=\"0\" \/><br \/>\n\u56e0\u6b64\uff0cNFA\u8f6c\u5316\u6210\u4e3aDFA\uff1a<br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\u8bcd\u6cd5\u5206\u6790(4)---NFA\u4e0eDFA\u7684\u8f6c\u5316\" src=\"http:\/\/img2.21tx.com\/2009\/09\/26\/13721.jpg\" width=\"292\" height=\"192\" border=\"0\" \/><br \/>\n&nbsp;<br \/>\n=========================================<br \/>\nDFA\u7684\u72b6\u6001<\/p>\n<div><\/div>\n<div>\u5728DFA\u4e2d\uff0c\u67d0\u4e2a\u72b6\u6001\u5bf9\u5e94\u5230\u03b5-NFA\u4e2d\u7684\u82e5\u5e72\u72b6\u6001\uff0c\u5e94\u6b64\u6211\u4eec\u5c06\u4f1a\u5f97\u5230\u4e0b\u9762\u8fd9\u6837\u7684\u4e00\u4e2a\u7ed3\u6784\u3002<\/div>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<pre>\nstruct DFA_State\n        {\n            set<epsilonNFA_State*> content;\n            bool                   bFlag;\n#ifdef _DEBUG\n            uint                   idx;\n#endif\n            DFA_State(const set<epsilonNFA_State*>& x) : content(x), bFlag(false)\n            {\n#ifdef _DEBUG\n                idx = inc();\n#endif\n            }\n            inline const bool operator==(const DFA_State& x)const\n            {\n                if (&x == this) return true;\n                return content == x.content;\n            }\n#ifdef _DEBUG\n            inline uint inc()\n            {\n                static uint i = 0;\n                return i++;\n            }\n#endif\n        };\n<\/pre>\n<div>\u53ef\u4ee5\u770b\u5230\uff0c\u4e3a\u4e86\u8c03\u8bd5\u65b9\u4fbf\u6211\u4eec\u5728\u7ed3\u6784\u4e2d\u5b9a\u4e49\u4e86\u72b6\u6001\u7684\u552f\u4e00ID\u4ee5\u53ca\u5bf9\u5e94\u5230\u03b5-NFA\u72b6\u6001\u7684\u96c6\u5408\u548c\u4e00\u4e2a\u6807\u8bb0\u4f4d\u3002<\/div>\n<div><\/div>\n<div>DFA\u7684\u8fb9<\/div>\n<div><\/div>\n<div>\u6839\u636e\u4e0a\u4e00\u7bc7\u7684\u7ecf\u9a8c\uff0c\u4e0d\u96be\u60f3\u5230DFA\u7684\u8fb9\u5e94\u8be5\u662f\u4ec0\u4e48\u6837\u7684\uff0c\u4e0b\u9762\u76f4\u63a5\u7ed9\u51fa\u4ee3\u7801\uff0c\u4e0d\u505a\u8bf4\u660e\u3002<\/div>\n<pre>\n  struct DFA_Edge\n        {\n            struct\n            {\n                Char_Type   char_value;\n                String_Type string_value;\n            }data;\n            enum Edge_Type\n            {\n                TUnknown = 0,\n                TNot     = 1,\n                TChar    = 2,\n                TString  = 4\n            };\n            uchar edge_type;\n            DFA_State* pFrom;\n            DFA_State* pTo;\n            DFA_Edge(const Char_Type& x, bool bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)\n            {\n                data.char_value = x;\n                edge_type = bNot ? (TChar | TNot) : TChar;\n            }\n            DFA_Edge(const String_Type& x, bool bNot, DFA_State* pFrom, DFA_State* pTo) : pFrom(pFrom), pTo(pTo)\n            {\n                data.string_value = x;\n                edge_type = bNot ? (TString | TNot) : TString;\n            }\n            inline const bool isNot()const\n            {\n                return (edge_type & TNot) == TNot;\n            }\n            inline const bool isChar()const\n            {\n                return (edge_type & TChar) == TChar;\n            }\n            inline const bool isString()const\n            {\n                return (edge_type & TString) == TString;\n            }\n            const Edge_Type edgeType()const\n            {\n                if (isChar()) return TChar;\n                else if (isString()) return TString;\n                else return TUnknown;\n            }\n            const bool operator<(const DFA_Edge&#038; x)const\n            {\n                return (ulong)pFrom + pTo < (ulong)x.pFrom + x.pTo;\n            }\n            const bool operator==(const DFA_Edge&#038; x)const\n            {\n                return pFrom == x.pFrom &#038;&#038; pTo == x.pTo;\n            }\n        };\n<\/pre>\n<div>\u7531\u4e8eDFA\u4e2d\u4e0d\u5b58\u5728\u03b5\u8fb9\uff0c\u5e94\u6b64DFA\u5c06\u4f1a\u5b58\u5728\u82e5\u5e72\u4e2a\u7ed3\u675f\u72b6\u6001\uff0c\u4f46\u4ed6\u53ea\u6709\u4e00\u4e2a\u5f00\u59cb\u72b6\u6001<\/div>\n<div><\/div>\n<pre>\nDFA_State*      pDFAStart;\nset<dfa_State*> pDFAEnds;\nset<dfa_Edge>   dfa_Edges;\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div>\u4e3a\u4e86\u4e0b\u4e00\u6b65\u5206\u6790\u7684\u9ad8\u6548\uff0c\u4ee5\u540e\u53ef\u80fd\u4f1a\u5c06\u8fd9\u91cc\u7684dfa_Edges\u540c\u6837\u4fee\u6539\u4e3ahashmap\u3002<\/div>\n<div><\/div>\n<div>\u81f3\u6b64DFA\u6240\u8981\u7528\u5230\u7684\u4e24\u4e2a\u7ed3\u6784\u8fc5\u901f\u7684\u4ecb\u7ecd\u5b8c\u4e86\u3002<\/div>\n<div><\/div>\n<div>\u5b50\u96c6\u6784\u9020\u7b97\u6cd5<\/div>\n<div><\/div>\n<div>\u901a\u8fc7\u5404\u79cd\u8d44\u6599\uff0c\u6211\u4eec\u4e0d\u96be\u53d1\u73b0\uff0c\u4ece\u03b5-NFA\u8f6c\u6362\u5230DFA\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6700\u5e38\u7528\u5c31\u662f\u5b50\u96c6\u6784\u9020\u7b97\u6cd5\u3002\u5b50\u96c6\u6784\u9020\u7b97\u6cd5\u7684\u4e3b\u8981\u601d\u60f3\u662f\u8ba9DFA\u7684\u6bcf\u4e2a\u72b6\u6001\u5bf9\u5e94NFA\u7684\u4e00\u4e2a\u72b6\u6001\u96c6\u3002\u8fd9\u4e2aDFA\u7528\u5b83\u7684\u72b6\u6001\u53bb\u8bb0\u4f4fNFA\u5728\u8bfb\u8f93\u5165\u7b26\u53f7\u540e\u8fbe\u5230\u7684\u6240\u6709\u72b6\u6001\u3002\uff08\u5f15\u81ea\u7f16\u8bd1\u539f\u7406\uff09\u5176\u7b97\u6cd5\u5982\u4e0b<\/div>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<div>\u8f93\u5165\uff1a\u4e00\u4e2aNFA N\u3002<\/div>\n<div>\u8f93\u51fa\uff1a\u4e00\u4e2a\u63a5\u53d7\u540c\u6837\u8bed\u8a00\u7684DFA D\u3002<\/div>\n<div>\u65b9\u6cd5\uff1a<\/div>\n<div>1.\u6c42\u53d6\u03b5-NFA\u521d\u59cb\u72b6\u6001\u7684\u03b5\u95ed\u5305\u4f5c\u4e3aDFA\u7684\u8d77\u59cb\u72b6\u6001\uff0c\u5e76\u5c06\u8fd9\u4e2a\u72b6\u6001\u52a0\u5165\u96c6\u5408C\u4e2d\uff0c\u4e14\u5b83\u662f\u672a\u6807\u8bb0\u7684\u3002\u540c\u65f6\u8bb0\u5f55\u5b83\u7684\u5411\u540e\u5b57\u7b26\u96c6\u3002<\/div>\n<div>2.\u4ece\u96c6\u5408C\u4e2d\u53d6\u51fa\u4e00\u4e2a\u672a\u88ab\u6807\u8bb0\u7684\u5b50\u96c6T\u548c\u5176\u5bf9\u5e94\u7684\u5b57\u7b26\u96c6\uff0c\u6807\u8bb0\u5b50\u96c6T\u3002<\/div>\n<div>3.\u4f7f\u7528\u4e0a\u4e00\u6b65\u53d6\u51fa\u7684\u5b57\u7b26\u96c6\u901a\u8fc7\u72b6\u6001\u8f6c\u79fb\u51fd\u6570\u6c42\u51fa\u8f6c\u79fb\u540e\u7684\u72b6\u6001\u96c6M\u3002<\/div>\n<div>4.\u6c42\u53d6\u4e0a\u4e00\u6b65\u5f97\u5230\u7684\u72b6\u6001\u96c6M\u7684\u03b5\u95ed\u5305U<\/div>\n<div>5.\u5982\u679cU\u4e0d\u5728\u96c6\u5408C\u4e2d\u5219\u5c06U\u4f5c\u4e3a\u672a\u88ab\u6807\u8bb0\u7684\u5b50\u96c6\u52a0\u5165C\u4e2d\uff0c\u540c\u65f6\u8bb0\u5f55\u5b83\u7684\u5411\u540e\u5b57\u7b26\u96c6\u3002\u68c0\u67e5\u72b6\u6001U\u4e2d\u662f\u5426\u5b58\u5728NFA\u4e2d\u7684\u7ec8\u7ed3\u72b6\u6001\uff0c\u82e5\u5b58\u5728\u5219\u5c06\u72b6\u6001U\u52a0\u5165\u5230pDFAEnds\u4e2d\u3002<\/div>\n<div>\u91cd\u590d2\uff0c3\uff0c4\uff0c5\u90e8\u76f4\u81f3\u96c6\u5408C\u4e2d\u4e0d\u5b58\u5728\u672a\u88ab\u6807\u8bb0\u7684\u72b6\u6001\u3002<\/div>\n<div>\u03b5\u95ed\u5305<\/div>\n<div><\/div>\n<div>\u03b5\u95ed\u5305\u662f\u6307\u4ece\u67d0\u4e2a\u72b6\u6001\u8d77\u53ea\u7ecf\u8fc7\u03b5\u8fb9\u8fbe\u5230\u7684\u5176\u4ed6\u72b6\u6001\u7684\u96c6\u5408\uff0c\u540c\u65f6\u8fd9\u4e2a\u72b6\u6001\u4e5f\u5c5e\u4e8e\u8fd9\u4e2a\u96c6\u5408\u4e2d\u3002\u5176\u7b97\u6cd5\u5982\u4e0b<\/div>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<div>\u8f93\u5165\uff1a\u72b6\u6001\u96c6k\u3002<\/div>\n<div>\u8f93\u51fa\uff1a\u72b6\u6001\u96c6U\u548c\u5176\u6240\u5bf9\u5e94\u7684\u5411\u540e\u5b57\u7b26\u96c6\u3002<\/div>\n<div>\u65b9\u6cd5\uff1a<\/div>\n<div>1.\u904d\u5386\u72b6\u6001\u96c6k\u4e2d\u7684\u6bcf\u4e2a\u72b6\u6001k'\u3002<\/div>\n<div>2.\u82e5k'\u4e0d\u5b58\u5728\u4e8e\u7ed3\u679c\u72b6\u6001\u96c6U\u4e2d\uff0c\u5c06k'\u63d2\u5165U\u4e2d\u3002<\/div>\n<div>3.\u5efa\u7acb\u4e00\u4e2a\u4e34\u65f6\u96c6\u5408tmp\uff0c\u5e76\u5c06k'\u63d2\u5165\u5176\u4e2d\u3002<\/div>\n<div>4.\u4ece\u4e34\u65f6\u96c6\u5408tmp\u4e2d\u53d6\u51fa\u4e00\u4e2a\u72b6\u6001p\u3002<\/div>\n<div>5.\u53d6\u51fa\u6240\u6709\u4ecep\u51fa\u53d1\u7684\u8fb9\uff0c\u82e5\u8fd9\u6761\u8fb9\u662f\u03b5\u8fb9\uff0c\u4e14\u62b5\u8fbe\u72b6\u6001\u4e0d\u5728\u7ed3\u679c\u72b6\u6001\u96c6U\u4e2d\uff0c\u5c06\u62b5\u8fbe\u7684\u72b6\u6001\u5206\u522b\u63d2\u5165\u7ed3\u679c\u72b6\u6001\u96c6U\u548c\u4e34\u65f6\u96c6\u5408tmp\u4e2d\u3002\u82e5\u8fd9\u6761\u8fb9\u662f\u5b57\u7b26\u96c6\u7684\u8fb9\u4e14\u8fd9\u6761\u8fb9\u6240\u5bf9\u5e94\u7684\u5b57\u7b26\u4e0d\u5728\u5411\u540e\u5b57\u7b26\u96c6\u4e2d\uff0c\u5219\u5c06\u5411\u540e\u5b57\u7b26\u63d2\u5165\u5411\u540e\u5b57\u7b26\u96c6\u4e2d\u3002<\/div>\n<div>6.\u5c06\u72b6\u6001p\u4ece\u4e34\u65f6\u96c6\u5408tmp\u4e2d\u5220\u9664\u3002<\/div>\n<div>\u5faa\u73af4\uff0c5\uff0c6\u90e8\u76f4\u81f3tmp\u4e2d\u4e0d\u5b58\u5728\u4efb\u4f55\u72b6\u6001\u4e3a\u6b62\u3002<\/div>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<div>\u7531\u4e8e\u5728\u751f\u6210\u03b5-NFA\u65f6\u4e0d\u5b58\u5728\u53ea\u6709\u03b5\u8fb9\u7684\u5faa\u73af\uff0c\u5e94\u6b64\u8fd9\u91cc\u4e0d\u4f1a\u4ea7\u751f\u6b7b\u5faa\u73af\u3002\u4e0b\u9762\u7ed9\u51fa\u5177\u4f53\u7684\u4ee3\u7801<\/div>\n<div><\/div>\n<pre>\n  void epsilonClosure(const set<epsilonNFA_State*>& k, EpsilonClosureInfo& info)\n        {\n            for (typename set<epsilonNFA_State*>::const_iterator i = k.begin(), m = k.end(); i != m; ++i)\n            {\n                info.states.insert(*i);\n                set<epsilonNFA_State*> tmp;\n                tmp.insert(*i);\n                while (!tmp.empty())\n                {\n                    EpsilonNFA_State* pState = *tmp.begin();\n                    for (typename vector<epsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[pState].begin(), n = epsilonNFA_Edges[pState].end(); j != n; ++j)\n                    {\n                        if (j->isEpsilon())\n                        {\n                            if (info.states.insert(j->pTo).second) tmp.insert(j->pTo);\n                        }\n                        else if (j->isChar()) info.chars.insert(pair<char_Type, bool>(j->data.char_value, j->isNot()));\n                        else if (j->isString()) info.strings.insert(pair<string_Type, bool>(j->data.string_value, j->isNot()));\n                    }\n                    tmp.erase(pState);\n                }\n            }\n        }\n<\/pre>\n<div><\/div>\n<div>\u5176\u4e2d\u7528\u5230\u7684EpsilonClosureInfo\u7ed3\u6784\u4e3a<\/div>\n<div><\/div>\n<pre>\n  struct EpsilonClosureInfo\n        {\n            set<epsilonNFA_State*>        states;\n            set<pair<char_Type, bool> >   chars;\n            set<pair<string_Type, bool> > strings;\n            EpsilonClosureInfo() {}\n            EpsilonClosureInfo(const set<epsilonNFA_State*>& states,\n                               const set<pair<char_Type, bool> >& chars,\n                               const set<pair<string_Type, bool> >& strings)\n                               : states(states)\n                               , chars(chars)\n                               , strings(strings) {}\n            EpsilonClosureInfo(const EpsilonClosureInfo& x)\n            {\n                states  = x.states;\n                chars   = x.chars;\n                strings = x.strings;\n            }\n        };\n<\/pre>\n<div>\u9700\u8981\u4fdd\u5b58\u7684\u662f\u72b6\u6001\u96c6\u548c\u5411\u540e\u5b57\u7b26\u96c6\u3002<\/div>\n<div><\/div>\n<div>\u72b6\u6001\u8f6c\u79fb\u51fd\u6570<\/div>\n<div><\/div>\n<div>\u901a\u8fc7\u72b6\u6001\u8f6c\u79fb\u51fd\u6570\uff0c\u8f93\u5165\u4e00\u4e2a\u96c6\u5408T\u548c\u4e00\u4e2a\u5b57\u7b26a\u5c06\u53ef\u5f97\u5230\u6240\u6709\u901a\u8fc7T\u4e2d\u7684\u6bcf\u4e00\u4e2a\u72b6\u6001\u548ca\u8fb9\u6240\u80fd\u8fbe\u5230\u7684\u72b6\u6001\u7684\u96c6\u5408\u3002\u5e94\u6b64\u4ee3\u7801\u5982\u4e0b<\/div>\n<div><\/div>\n<pre>\n   set<epsilonNFA_State*> move(const DFA_State& t, const Char_Type& c, bool bNot)\n        {\n            set<epsilonNFA_State*> result;\n            for (typename set<epsilonNFA_State*>::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)\n            {\n                for (typename vector<epsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)\n                {\n                    if (j->isChar() && j->data.char_value == c && j->isNot() == bNot) result.insert(j->pTo);\n                }\n            }\n            return result;\n        }\n        set<epsilonNFA_State*> move(const DFA_State& t, const String_Type& s, bool bNot)\n        {\n            set<epsilonNFA_State*> result;\n            for (typename set<epsilonNFA_State*>::const_iterator i = t.content.begin(), m = t.content.end(); i != m; ++i)\n            {\n                for (typename vector<epsilonNFA_Edge>::const_iterator j = epsilonNFA_Edges[*i].begin(), n = epsilonNFA_Edges[*i].end(); j != n; ++j)\n                {\n                    if (j->isString() && j->data.string_value == s && j->isNot() == bNot) result.insert(j->pTo);\n                }\n            }\n            return result;\n        }\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div>\u4e3a\u4e86\u5206\u522b\u652f\u6301Char_Type\u548cString_Type\u7684\u5b57\u7b26\u6211\u4eec\u5b9a\u4e49\u4e86\u4e24\u4e2amove\u51fd\u6570\u3002<\/div>\n<div><\/div>\n<div>\u6700\u540e\u6211\u4eec\u7ed9\u51fa\u5b50\u96c6\u6784\u9020\u7b97\u6cd5\u7684\u4ee3\u7801<\/div>\n<div><\/div>\n<div><\/div>\n<pre>\n   void buildDFA()\n        {\n            set<epsilonNFA_State*> start;\n            start.insert(pEpsilonStart);\n            typedef pair<dfa_State*, EpsilonClosureInfo> c_type;\n            map<size_t, list<c_type> > c;\n            queue<c_type> c2;\n            pDFAStart = DFA_State_Alloc::allocate();\n            EpsilonClosureInfo info;\n            epsilonClosure(start, info);\n            construct(pDFAStart, info.states);\n            c_type ct(pDFAStart, info);\n            c[info.states.size()].push_back(ct);\n            c2.push(ct);\n            if (isEndDFAStatus(pDFAStart)) pDFAEnds.insert(pDFAStart);\n            context.dfa_States.insert(pDFAStart);\n            while (!c2.empty())\n            {\n                DFA_State* t = c2.front().first;\n                set<pair<char_Type, bool> > chars = c2.front().second.chars;\n                set<pair<string_Type, bool> > strings = c2.front().second.strings;\n                t->bFlag = true;\n                for (typename set<pair<char_Type, bool> >::const_iterator i = chars.begin(), m = chars.end(); i != m; ++i)\n                {\n                    EpsilonClosureInfo info;\n                    epsilonClosure(move(*t, i->first, i->second), info);\n                    DFA_State* p = getDFAState(info.states, c);\n                    if (p) \/\/ \u5982\u679c\u8fd9\u4e2a\u72b6\u6001\u5df2\u5b58\u5728\n                    {\n                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, p));\n                    }\n                    else\n                    {\n                        DFA_State* pState = DFA_State_Alloc::allocate();\n                        construct(pState, info.states);\n                        context.dfa_States.insert(pState);\n                        if (isEndDFAStatus(pState)) pDFAEnds.insert(pState);\n                        c_type ct(pState, info);\n                        c[info.states.size()].push_back(ct);\n                        c2.push(ct);\n                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, pState));\n                    }\n                }\n                for (typename set<pair<string_Type, bool> >::const_iterator i = strings.begin(), m = strings.end(); i != m; ++i)\n                {\n                    EpsilonClosureInfo info;\n                    epsilonClosure(move(*t, i->first, i->second), info);\n                    DFA_State* p = getDFAState(info.states, c);\n                    if (p) \/\/ \u5982\u679c\u8fd9\u4e2a\u72b6\u6001\u5df2\u5b58\u5728\n                    {\n                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, p));\n                    }\n                    else\n                    {\n                        DFA_State* pState = DFA_State_Alloc::allocate();\n                        construct(pState, info.states);\n                        context.dfa_States.insert(pState);\n                        if (isEndDFAStatus(pState)) pDFAEnds.insert(pState);\n                        c_type ct(pState, info);\n                        c[info.states.size()].push_back(ct);\n                        c2.push(ct);\n                        dfa_Edges.insert(DFA_Edge(i->first, i->second, t, pState));\n                    }\n                }\n                c2.pop();\n            }\n        }\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div>\u5c3e\u58f0<\/div>\n<div><\/div>\n<div>\u540c\u6837\u6211\u4eec\u6765\u7f16\u5199\u4e00\u4e2a\u51fd\u6570\u6765\u6253\u5370\u51faDFA\u3002<\/div>\n<div><\/div>\n<div><\/div>\n<pre>\n void printDFA()\n        {\n            printf(\"---------- DFA Start ----------n\");\n            set<dfa_State*> tmp;\n            for (typename set<dfa_Edge>::const_iterator i = dfa_Edges.begin(), m = dfa_Edges.end(); i != m; ++i)\n            {\n                printf(\"%03d -> %03d\", i->pFrom->idx, i->pTo->idx);\n                switch (i->edgeType())\n                {\n                case DFA_Edge::TChar:\n                    printf(\"(%c)\", i->data.char_value);\n                    break;\n                case DFA_Edge::TString:\n                    printf(\"(%s)\", i->data.string_value.c_str());\n                    break;\n                default:\n                    break;\n                }\n                if (i->isNot()) printf(\"(not)\");\n                printf(\"n\");\n                tmp.insert(i->pFrom);\n                tmp.insert(i->pTo);\n            }\n            printf(\"start: %03d -> ends: \", pDFAStart->idx);\n            for (typename set<dfa_State*>::const_iterator i = pDFAEnds.begin(), m = pDFAEnds.end(); i != m; ++i)\n            {\n                printf(\"%03d \", (*i)->idx);\n            }\n            printf(\"n\");\n#if DEBUG_LEVEL == 3\n            printf(\"-------------------------------n\");\n            for (typename set<dfa_State*>::const_iterator i = tmp.begin(), m = tmp.end(); i != m; ++i)\n            {\n                printf(\"State: %03dn\", (*i)->idx);\n                for (typename set<epsilonNFA_State*>::const_iterator j = (*i)->content.begin(), n = (*i)->content.end(); j != n; ++j)\n                {\n                    printf(\"%03d \", (*j)->idx);\n                }\n                printf(\"n\");\n            }\n#endif\n            printf(\"----------- DFA End -----------n\");\n        }\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div><\/div>\n<div>\u6700\u540e\u6211\u4eec\u52a0\u5165\u6d4b\u8bd5\u4ee3\u7801<\/div>\n<div><\/div>\n<pre>\nRule_Type::Context context;\nRule_Type a('a', context), b('b', context), d('d', context);\nRule_Type result = (a - d).opt() + (+b | !(a + b));\nresult.buildDFA();\n#ifdef _DEBUG\nresult.printEpsilonNFA();\nresult.printDFA();\n#endif\n<\/pre>\n<div><\/div>\n<div><\/div>\n<div>\u53ef\u6253\u5370\u51fa\u5982\u4e0b\u5185\u5bb9<\/div>\n<div><\/div>\n<div><img decoding=\"async\" alt=\"DFA\" src=\"http:\/\/www.2cto.com\/uploadfile\/2013\/0227\/20130227095937349.png\" \/><\/div>\n<div>\u753b\u6210\u56fe\u5982\u4e0b<\/div>\n<div><img decoding=\"async\" alt=\"DFA\u56fe\" src=\"http:\/\/www.2cto.com\/uploadfile\/2013\/0227\/20130227095937628.png\" \/><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u6587\u6765\u6e90\u53ca\u53c2\u8003\u8d44\u6599\uff1a http:\/\/hi.baidu.com\/beanchx\/item\/b153390de0691827a1312d49 http:\/\/www.2cto.com\/kf\/201302\/191521.html http:\/\/dev.21tx.com\/2009\/09\/26\/11354.html \u30001. \u5b50\u96c6\u6784\u9020(Subset Construction) \u8fd9\u662f\u4e00\u4e2a\u8f6c\u6362NFA\u5230DFA\u7684\u7b97\u6cd5\u3002\u6211\u4eec\u77e5\u9053NFA\u548cDFA\u7684\u533a\u522b\u6700\u4e3b\u8981\u7684\u5c31\u662f\u4e00\u4e2a\u72b6\u6001\u548c\u4e00\u4e2ainput symbol\u662f\u5426\u80fd\u591f\u786e\u5b9a\u4e00\u4e2a\u72b6\u6001\u7684\u95ee\u9898\uff0c\u5bf9\u4e8eNFA\uff0c\u5b83\u5c06\u786e\u5b9a\u4e00\u4e2a\u7ec4\u72b6\u6001\uff0c\u800cDFA\u5c06\u786e\u5b9a\u4e00\u4e2a\u72b6\u6001\uff0c\u56e0\u6b64\uff0c\u6211\u4eec\u6709\u4e00\u4e2a\u5f88\u597d\u7684\u529e\u6cd5\u5c31\u662f\u628aNFA\u7684\u72b6\u6001\u96c6\u5bf9\u5e94\u6bcf\u4e2aDFA\u7684\u72b6\u6001\uff0c\u8fd9\u5c31\u662fsubset construction\u7684\u601d\u60f3\uff0c\u4e0d\u8fc7\u8fd9\u53ea\u662f\u5927\u6982\u6cdb\u6cdb\u800c\u8bba\uff0c\u6211\u4eec\u9700\u8981\u66f4\u52a0\u660e\u786e\u7684\u8ba4\u8bc6 1) NFA\u5728\u4efb\u4f55\u4e00\u4e2ainput symbol\u4e0b\uff0c\u6620\u5c04\u7684\u72b6\u6001\u96c6(\u901a\u8fc7move\u51fd\u6570\uff0c\u8fd9\u4e2a\u96c6\u5408\u901a\u5e38\u7528T\u5b57\u6bcd\u8868\u793a)\u5e94\u8be5\u88ab\u77e5\u9053 2) \u5fc5\u987b\u4fdd\u8bc11)\u4e2d\u72b6\u6001\u96c6\u90fd\u5bf9\u5e94\u4e86DFA\u4e2d\u7684\u4e00\u4e2a\u72b6\u6001 \u3000\u3000\u5177\u4f53\u7b97\u6cd5\uff1a Input : \u4e00\u4e2aNFA N Output : \u63a5\u53d7\u76f8\u540c\u8bed\u8a00\u7684DFA D Method : \u4e3aD\u6784\u67b6\u4e00\u4e2atransition table(\u8f6c\u6362\u8868) Dtran\uff0c\u6bcf\u4e2aDFA\u7684\u72b6\u6001\u662f\u4e00\u4e2aNFA\u7684\u72b6\u6001\u96c6\u5408(\u8fd9\u91cc\u4e00\u5b9a\u8981\u6ce8\u610f\u524d\u9762\u8bf4\u8fc7\u76841)2)\u4e24\u70b9)\u3002\u6211\u4eec\u5b9a\u4e49\u4e00\u4e9b\u64cd\u4f5c\uff1a s \u8868\u793aNFA\u7684\u72b6\u6001\uff0cT \u8868\u793aNFA\u7684\u72b6\u6001\u96c6\u5408\uff0ca\u8868\u793a\u4e00\u4e2ainput symbol \u03b5-transition(\u03b5\u8f6c\u6362)\u5c31\u662f\u8bf4input symbol\u4e3a\u03b5\u65f6\u7684transition(\u8f6c\u6362) &nbsp; \u64cd\u4f5c(operation) &nbsp; \u63cf\u8ff0(description) &nbsp; \u03b5-closure(s) &nbsp; \u4eceNFA\u7684\u72b6\u6001s\u51fa\u53d1\uff0c\u53ea\u901a\u8fc7\u03b5-transition\u5230\u8fbe\u7684NFA\u7684\u72b6\u6001\u96c6\u5408 &nbsp; \u03b5-closure(T) &nbsp; NFA\u7684\u96c6\u5408T\u4e2d\u7684\u72b6\u6001p\uff0c\u53ea\u901a\u8fc7\u03b5-transition\u5230\u8fbe\u7684NFA\u7684\u72b6\u6001\u96c6\u5408\uff0c\u518d\u6c42\u8fd9\u4e9b\u96c6\u5408\u7684\u4ea4\u96c6\u3002\u7528\u6570\u5b66\u8868\u8fbe\u5c31\u662f {p|p \u5c5e\u4e8e \u03b5-closure(t) , t\u5c5e\u4e8eT} &nbsp; move(T,a) &nbsp; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-250","post","type-post","status-publish","format-standard","hentry","category-study"],"_links":{"self":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=250"}],"version-history":[{"count":0,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=\/wp\/v2\/posts\/250\/revisions"}],"wp:attachment":[{"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dayandcarrot.space\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}