提交 4475c7af 编写于 作者: xindoo's avatar xindoo

增加dfa和nfa图的输出,修改部分代码

上级 a87d56e1
......@@ -9,10 +9,11 @@ import xyz.xindoo.re.nfa.NFAGraph;
import xyz.xindoo.re.nfa.NFAState;
import xyz.xindoo.re.nfa.strategy.MatchStrategy;
import xyz.xindoo.re.nfa.strategy.MatchStrategyManager;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
......@@ -36,6 +37,49 @@ public class Regex {
this.dfaGraph = dfaGraph;
}
public void printNfa() {
Queue<State> queue = new ArrayDeque<>();
Set<Integer> addedStates = new HashSet<>();
queue.add(nfaGraph.start);
addedStates.add(nfaGraph.start.getId());
while (!queue.isEmpty()) {
State curState = queue.poll();
for (Map.Entry<String, Set<State>> entry : curState.next.entrySet()) {
String key = entry.getKey();
Set<State> nexts = entry.getValue();
for (State next : nexts) {
System.out.printf("%2d->%2d %s\n", curState.getId(), next.getId(), key);
if (!addedStates.contains(next.getId())) {
queue.add(next);
addedStates.add(next.getId());
}
}
}
}
}
public void printDfa() {
Queue<State> queue = new ArrayDeque<>();
Set<String> addedStates = new HashSet<>();
queue.add(dfaGraph.start);
addedStates.add(((DFAState)dfaGraph.start).getAllStateIds());
while (!queue.isEmpty()) {
State curState = queue.poll();
for (Map.Entry<String, Set<State>> entry : curState.next.entrySet()) {
String key = entry.getKey();
Set<State> nexts = entry.getValue();
for (State next : nexts) {
System.out.printf("%s -> %s %s \n", ((DFAState)curState).getAllStateIds(),((DFAState)next).getAllStateIds(), key);
if (!addedStates.contains(((DFAState)next).getAllStateIds())) {
queue.add(next);
addedStates.add(((DFAState)next).getAllStateIds());
}
}
}
}
}
private static NFAGraph regex2nfa(String regex) {
Reader reader = new Reader(regex);
NFAGraph nfaGraph = null;
......@@ -162,7 +206,7 @@ public class Regex {
finishedEdges.add(edge);
Set<State> efinishedState = new HashSet<>();
for (State state : curState.nfaStates) {
List<State> edgeStates = state.next.getOrDefault(edge, Collections.emptyList());
Set<State> edgeStates = state.next.getOrDefault(edge, Collections.emptySet());
nextStates.addAll(edgeStates);
for (State eState : edgeStates) { // 添加E可达节点
if (efinishedState.contains(eState)) {
......@@ -225,7 +269,7 @@ public class Regex {
if (curNFAState.isEndState()) {
return true;
}
for (State nextState : curNFAState.next.getOrDefault(Constant.EPSILON, Collections.emptyList())) {
for (State nextState : curNFAState.next.getOrDefault(Constant.EPSILON, Collections.emptySet())) {
if (isMatch(text, pos, nextState)) {
return true;
}
......@@ -233,7 +277,7 @@ public class Regex {
return false;
}
for (Map.Entry<String, List<State>> entry : curNFAState.next.entrySet()) {
for (Map.Entry<String, Set<State>> entry : curNFAState.next.entrySet()) {
String edge = entry.getKey();
if (Constant.EPSILON.equals(edge)) {
for (State nextState : entry.getValue()) {
......
......@@ -3,9 +3,12 @@ package xyz.xindoo.re;
public class RegexTest {
public static void main(String[] args) throws Exception {
Regex regex = Regex.compile("a(b|c)*");
regex.printNfa();
System.out.println("");
regex.printDfa();
// Regex regex = Regex.compile("a\\s+.+b");
System.out.println(regex.isMatch("ac"));
System.out.println(regex.isMatch("ac"));
System.out.println(regex.isMatch("acc"));
System.out.println(regex.isMatch("a"));
System.out.println(regex.isMatch("a bcccdb"));
System.out.println(regex.isMatch("ab"));
......@@ -16,7 +19,7 @@ public class RegexTest {
System.out.println("*********");
System.out.println(regex.isMatch("ac", 1));
System.out.println(regex.isMatch("ac", 1));
System.out.println(regex.isMatch("acc", 1));
System.out.println(regex.isMatch("a", 1));
System.out.println(regex.isMatch("a bcccdb", 1));
System.out.println(regex.isMatch("ab", 1));
......
......@@ -2,8 +2,10 @@ package xyz.xindoo.re.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class State {
protected static int idCnt = 0;
......@@ -14,15 +16,15 @@ public class State {
this.id = idCnt++;
}
public Map<String, List<State>> next = new HashMap<>();
public Map<String, Set<State>> next = new HashMap<>();
public void addNext(String edge, State nfaState) {
List<State> list = next.get(edge);
if (list == null) {
list = new ArrayList<>();
next.put(edge, list);
Set<State> set = next.get(edge);
if (set == null) {
set = new HashSet<>();
next.put(edge, set);
}
list.add(nfaState);
set.add(nfaState);
}
public void setStateType() {
......
......@@ -8,9 +8,10 @@ import java.util.Set;
public class DFAGraph {
private Map<String, DFAState> map = new HashMap<>();
private Map<String, DFAState> nfaStates2dfaState = new HashMap<>();
public DFAState start = new DFAState();
// 这里用map保存NFAState结合是已有对应的DFAState, 有就直接拿出来用
public DFAState getOrBuild(Set<State> states) {
String allStateIds = "";
int[] ids = states.stream()
......@@ -21,10 +22,10 @@ public class DFAGraph {
allStateIds += "#";
allStateIds += id;
}
if (!map.containsKey(allStateIds)) {
if (!nfaStates2dfaState.containsKey(allStateIds)) {
DFAState dfaState = new DFAState(allStateIds, states);
map.put(allStateIds, dfaState);
nfaStates2dfaState.put(allStateIds, dfaState);
}
return map.get(allStateIds);
return nfaStates2dfaState.get(allStateIds);
}
}
......@@ -6,6 +6,7 @@ import java.util.Set;
public class DFAState extends State {
public Set<State> nfaStates = new HashSet<>();
// 保存对应NFAState的id,一个DFAState可能是多个NFAState的集合,所以拼接成String
private String allStateIds;
public DFAState() {
this.stateType = 2;
......@@ -21,4 +22,8 @@ public class DFAState extends State {
}
}
}
public String getAllStateIds() {
return allStateIds;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册