标签:
import java.util.ArrayList; import java.util.Map; import java.util.TreeMap; class Edge{ private int u, v; private char key; public Edge(int u, int v, char key) { super(); this.u = u; this.v = v; this.key = key; } @Override public String toString() { return u + "->" + v + " " + key; } } class NFA{ private String formal_ceremony;//正规式字符串 private int cnt_node=1;//记录节点的个数 private Map<Integer, Integer> endNode = new TreeMap<Integer, Integer>();//每一个开始节点对应的终端节点 ArrayList<Edge> nodeAl = new ArrayList<Edge>(); public NFA(String formal_ceremony) { super(); this.formal_ceremony = formal_ceremony; } public boolean kernel_way(int fa, int ld, int rd, boolean isClosure){//fa表示区间的开始点,正规式的区间[ld, rd], isClosure表示这段区间查是否存在闭包 if(ld < 0 || rd >= formal_ceremony.length()){ System.out.println("正规式不正确---发生数组越界!"); return false; } int pre_node = fa; int inBracket = 0;//判断‘|‘是否在括弧内 for(int i=ld; i<=rd; ++i){ if(formal_ceremony.charAt(i)==‘(‘) ++inBracket; else if(formal_ceremony.charAt(i)==‘)‘) --inBracket; else if(formal_ceremony.charAt(i)==‘|‘ && 0==inBracket){ if(!kernel_way(fa, ld, i-1, isClosure)) return false; if(!kernel_way(fa, i+1, rd, isClosure)) return false; return true; } } for(int i=ld; i<=rd; ++i){ if(formal_ceremony.charAt(i)==‘(‘){//又是一个子区间 //寻找和 该 ‘(‘相匹配的‘)‘ int cntLeftBracket = 0;//统计遍历过程中‘(‘出现的次数,遇到‘)‘减去1 int posRightBracket = -1;//记录相匹配的‘)‘的位置 int posLeftBracket = i; for(int j=i+1; j<=rd; ++j){ if(formal_ceremony.charAt(j)==‘(‘) ++cntLeftBracket; else if(formal_ceremony.charAt(j)==‘)‘){ if(cntLeftBracket == 0){ posRightBracket = j; break; } --cntLeftBracket; } } if(posRightBracket == -1){//出错 System.out.println("正规式出错----括弧不匹配!"); return false; } int nodeFather = 0;//括弧内正则式的开始节点 if(posRightBracket+1 <= rd && formal_ceremony.charAt(posRightBracket+1)==‘*‘){ i = posRightBracket+1;//过滤掉"()*" nodeAl.add(new Edge(pre_node, ++cnt_node, ‘$‘));//表示这一条边为空 pre_node = cnt_node; nodeFather = cnt_node; nodeAl.add(new Edge(pre_node, ++cnt_node, ‘$‘));//表示这一条边为空 pre_node = cnt_node; //处理()*括弧内的正规式 if(!kernel_way(nodeFather, posLeftBracket+1, posRightBracket-1, true)) return false; } else { nodeFather = pre_node; if(!kernel_way(nodeFather, posLeftBracket+1, posRightBracket-1, false))//对于"(101)", 看成101 return false; i = posRightBracket; } } else {//单个字符 if(formal_ceremony.charAt(i)==‘)‘) continue; if(i+1 <= rd && formal_ceremony.charAt(i+1)==‘*‘){ nodeAl.add(new Edge(pre_node, ++cnt_node, ‘$‘));//表示这一条边为空 pre_node = cnt_node; nodeAl.add(new Edge(pre_node, pre_node, formal_ceremony.charAt(i)));//自身到自身一条边 if(i+1==rd && isClosure) nodeAl.add(new Edge(pre_node, fa, ‘$‘));//表示这一条边为空并且是连接到父亲节点 else{ if(endNode.containsKey(fa)) nodeAl.add(new Edge(pre_node, endNode.get(fa), ‘$‘)); else{ nodeAl.add(new Edge(pre_node, ++cnt_node, ‘$‘));//表示这一条边为空 if(i==rd) endNode.put(fa, cnt_node);//记录非闭包状态下 第一个节点对应的最后一个节点 } } pre_node = cnt_node; ++i;//过滤* } else { if(i==rd && isClosure){//是闭包的情况 nodeAl.add(new Edge(pre_node, fa, formal_ceremony.charAt(i))); } else{ if(endNode.containsKey(fa)) nodeAl.add(new Edge(pre_node, endNode.get(fa), formal_ceremony.charAt(i))); else{ nodeAl.add(new Edge(pre_node, ++cnt_node, formal_ceremony.charAt(i))); if(i==rd) endNode.put(fa, cnt_node);//记录非闭包状态下 第一个节点对应的最后一个节点 } } pre_node = cnt_node; } } } return true; } public void outputNFA(){ for(Edge e : nodeAl) System.out.println(e); } } /* * 将正规式转换成NFA * */ public class ToNFA { public static void main(String[] args){ // String formal_ceremony = "1(1010*|1(010)*1)*0"; // String formal_ceremony = "1(0|1)*101"; // String formal_ceremony = "0*1*(010)0*1*"; // String formal_ceremony = "(0|1|2)*"; // String formal_ceremony = "0|1"; // String formal_ceremony = "0|1|2|3"; // String formal_ceremony = "(0|1|6)|(2|3)|(4|5)"; // String formal_ceremony = "(0|1)*|(2|3)*"; String formal_ceremony = "((10)|(01)*|(0|1))"; NFA nfa = new NFA(formal_ceremony); if(nfa.kernel_way(1, 0, formal_ceremony.length()-1, false)) nfa.outputNFA(); } }
标签:
原文地址:http://www.cnblogs.com/hujunzheng/p/4421132.html