package pl.edu.amu.wmi.daut.base; import java.util.HashMap; import java.util.LinkedList; import java.util.List; /** * Rozwinięty algorytm niedeterministycznego automatu przy pomocy metody Thompsona. Różni się tym * od wersji wcześniejszej, że posiada tabele przejść, w której zapisywane są wszystkie wykonane * przejśćia. Gdy ma się powtórzyć identyczne przejście, algorytm zczytuje wartość z tabeli bez * potrzeby przeszukiwania automatu. */ public class DevelopedNondeterministicAutomatonByThompsonApproach extends NondeterministicAutomatonByThompsonApproach implements Acceptor { private HashMap<List<State>, HashMap<String, List<State>>> map = new HashMap<List<State>, HashMap<String, List<State>>>(); DevelopedNondeterministicAutomatonByThompsonApproach( AutomatonSpecification specification) { super(specification); } @Override public boolean accepts(String text) { boolean accept = false; boolean added; boolean skip; int i = 0; int limit = text.length(); List<State> currentStates = new LinkedList<State>(); List<State> temporaryStates = new LinkedList<State>(); List<State> pStates = new LinkedList<State>(); List<State> startMapStates = new LinkedList<State>(); currentStates.add(getSpecification().getInitialState()); do { skip = false; if (map.containsKey(currentStates)) { HashMap<String, List<State>> temporaryMap = new HashMap<String, List<State>>(); temporaryMap.putAll(map.get(currentStates)); if (i == limit || limit == 0) { if (temporaryMap.containsKey("")) { currentStates.clear(); currentStates.addAll(temporaryMap.get("")); skip = true; } else { startMapStates.addAll(currentStates); } } else { char[] ch = new char[1]; ch[0] = text.charAt(i); String str = new String(ch); if (temporaryMap.containsKey(str)) { currentStates.clear(); currentStates.addAll(temporaryMap.get(str)); skip = true; } else { startMapStates.addAll(currentStates); } } } else { startMapStates.addAll(currentStates); } if (!skip) { do { added = false; for (State someState : currentStates) { List<State> epsilonStates = new LinkedList<State>(epsilonClosure(someState)); for (State eState : epsilonStates) { if (!currentStates.contains(eState) && !pStates.contains(eState)) { pStates.add(eState); added = true; } } } currentStates.addAll(pStates); pStates.clear(); } while (added); } if (limit != 0 && i != limit && !skip) { for (State someState : currentStates) { List<OutgoingTransition> someStateTransitions = new LinkedList<OutgoingTransition>( getSpecification().allOutgoingTransitions(someState)); for (OutgoingTransition transition : someStateTransitions) { if (transition.getTransitionLabel().canAcceptCharacter(text.charAt(i)) && !temporaryStates.contains(transition.getTargetState())) { temporaryStates.add(transition.getTargetState()); } } } currentStates.clear(); currentStates.addAll(temporaryStates); temporaryStates.clear(); } if (!skip) { HashMap<String, List<State>> temporaryMap = new HashMap<String, List<State>>(); if (limit == 0 || i == limit) { temporaryMap.put("", currentStates); map.put(startMapStates, temporaryMap); startMapStates.clear(); } else { char[] ch = new char[1]; ch[0] = text.charAt(i); String str = new String(ch); temporaryMap.put(str, currentStates); map.put(startMapStates, temporaryMap); startMapStates.clear(); } } i++; } while (i <= limit); for (State state : currentStates) { if (getSpecification().isFinal(state)) { accept = true; } } return accept; } }