private static void _DrawNfaPair(Canvas cv, NfaNode node) { if (node != null && !visited[node.nodenum]) { visited[node.nodenum] = true; //画当前node的圆 var circle = GetCircle(node.deep * distanceX, node.deepnum * distanceY); cv.Children.Add(circle); cv.Children.Add(GetNumTextBlock( node.deep * distanceX, node.deepnum * distanceY, node.nodenum.ToString())); //补上线、文字,同时递归 string text = ""; if (node.next1 != null) { //线 var path = GetNext1Path(node.deep * distanceX, node.deepnum * distanceY, node.next1.deep * distanceX, node.next1.deepnum * distanceY); cv.Children.Add(path); //文字 if (node.edge == -1) { text = "ε"; } else if (node.edge == -2) { text = "[" + node.charsetstring + "]"; } else { text = ((char)node.edge).ToString(); } var tb = GetTextBlock(node.deep * distanceX, node.deepnum * distanceY, node.next1.deep * distanceX, node.next1.deepnum * distanceY, text); cv.Children.Add(tb); _DrawNfaPair(cv, node.next1); } if (node.next2 != null) { //线 var path = GetNext2Path(node.deep * distanceX, node.deepnum * distanceY, node.next2.deep * distanceX, node.next2.deepnum * distanceY); cv.Children.Add(path); //文字 var tb = GetTextBlock(node.deep * distanceX, node.deepnum * distanceY, node.next2.deep * distanceX, node.next2.deepnum * distanceY, text); cv.Children.Add(tb); _DrawNfaPair(cv, node.next2); } } }
//由字符串表示的字符集构建单个自动机 private static NfaPair CreatNfaPair(string charsetstring) { NfaPair np = new NfaPair(); NfaNode s = new NfaNode(), e = new NfaNode(); s.edge = -2; s.charsetstring = charsetstring; s.next1 = e; np.start = s; np.end = e; np.count += 2; return(np); }
private static int[] deeps; //对应深度节点数 //由字符构建单个自动机 private static NfaPair CreatNfaPair(char c) { NfaPair np = new NfaPair(); NfaNode s = new NfaNode(), e = new NfaNode(); s.edge = c; s.next1 = e; np.start = s; np.end = e; np.count += 2; return(np); }
//形成?闭包自动机 private static NfaPair DoQuestCollapse(NfaPair nfaPair) { NfaPair np = new NfaPair(); NfaNode before = new NfaNode(), after = new NfaNode(); np.start = before; np.end = after; np.count += 2; //前面连接 before.next1 = nfaPair.start; before.edge = -1; //后面连接 nfaPair.end.next1 = after; nfaPair.end.edge = -1; //现在头连尾 before.next2 = after; np.count += nfaPair.count; return(np); }
private static void _DFS(NfaNode node, int deep) { if (node != null && !visited[node.nodenum]) { node.deep = deep + 1; //可能字符、序号入数组 if (node.edge == -2) { charstrings.Add(node.charsetstring); } else if (node.edge >= 0) { chars.Add(node.edge); } nfanodes[node.nodenum] = node; visited[node.nodenum] = true; node.deepnum = ++deeps[node.deep]; _DFS(node.next1, node.deep); _DFS(node.next2, node.deep); } }
private static int distanceY = 50; //节点纵向基本距离 //遍历一次树,计算深度、同深度节点数量、可能字符、序号入数组,重置交由DrawNfaPair处理 private static void DFS(NfaNode root) { _DFS(root, 0); }