/** * Retrieves Strings corresponding to all valid _transition paths from a given node that satisfy a * given condition. * * @param strHashSet a HashSet of Strings to contain all those in the MDAG satisfying {@code * searchCondition} with {@code conditionString} * @param searchCondition the SearchCondition enum field describing the type of relationship that * Strings contained in the MDAG must have with {@code conditionString} in order to be * included in the result set * @param searchConditionString the String that all Strings in the MDAG must be related with in * the fashion denoted by {@code searchCondition} in order to be included in the result set * @param prefixString the String corresponding to the currently traversed _transition path * @param node an int denoting the starting index of a SimpleMDAGNode's _transition set in * mdagDataArray */ private void getStrings( HashSet<String> strHashSet, SearchCondition searchCondition, String searchConditionString, String prefixString, SimpleMDAGNode node) { int transitionSetBegin = node.getTransitionSetBeginIndex(); int onePastTransitionSetEnd = transitionSetBegin + node.getOutgoingTransitionSetSize(); // Traverse all the valid _transition paths beginning from each _transition in // transitionTreeMap, inserting the // corresponding Strings in to strHashSet that have the relationship with conditionString // denoted by searchCondition for (int i = transitionSetBegin; i < onePastTransitionSetEnd; i++) { SimpleMDAGNode currentNode = mdagDataArray[i]; String newPrefixString = prefixString + currentNode.getLetter(); if (currentNode.isAcceptNode() && searchCondition.satisfiesCondition(newPrefixString, searchConditionString)) strHashSet.add(newPrefixString); // Recursively call this to traverse all the valid _transition paths from currentNode getStrings(strHashSet, searchCondition, searchConditionString, newPrefixString, currentNode); } ///// }
/** * 是否包含<br> * Determines whether a String is present in the MDAG. * * @param str the String to be searched for * @return true if {@code str} is present in the MDAG, and false otherwise */ public boolean contains(String str) { if (sourceNode != null) // if the MDAG hasn't been simplified { MDAGNode targetNode = sourceNode.transition(str.toCharArray()); return (targetNode != null && targetNode.isAcceptNode()); } else { SimpleMDAGNode targetNode = simplifiedSourceNode.transition(mdagDataArray, str.toCharArray()); return (targetNode != null && targetNode.isAcceptNode()); } }
@Override public void save(DataOutputStream out) throws Exception { simplify(); out.writeInt(charTreeSet.size()); for (Character character : charTreeSet) { out.writeChar(character); } simplifiedSourceNode.save(out); out.writeInt(mdagDataArray.length); for (SimpleMDAGNode simpleMDAGNode : mdagDataArray) { simpleMDAGNode.save(out); } }
/** * 前缀查询<br> * Retrieves all the Strings in the MDAG that begin with a given String. * * @param prefixStr a String that is the prefix for all the desired Strings * @return a HashSet containing all the Strings present in the MDAG that begin with {@code * prefixString} */ public HashSet<String> getStringsStartingWith(String prefixStr) { HashSet<String> strHashSet = new HashSet<String>(); if (sourceNode != null) // if the MDAG hasn't been simplified { MDAGNode originNode = sourceNode.transition( prefixStr); // attempt to _transition down the path denoted by prefixStr if (originNode != null) // if there a _transition path corresponding to prefixString (one or more stored // Strings begin with prefixString) { if (originNode.isAcceptNode()) strHashSet.add(prefixStr); getStrings( strHashSet, SearchCondition.PREFIX_SEARCH_CONDITION, prefixStr, prefixStr, originNode .getOutgoingTransitions()); // retrieve all Strings that extend the _transition path // denoted by prefixStr } } else { SimpleMDAGNode originNode = SimpleMDAGNode.traverseMDAG( mdagDataArray, simplifiedSourceNode, prefixStr); // attempt to _transition down the path denoted by prefixStr if (originNode != null) // if there a _transition path corresponding to prefixString (one or more stored // Strings begin with prefixStr) { if (originNode.isAcceptNode()) strHashSet.add(prefixStr); getStrings( strHashSet, SearchCondition.PREFIX_SEARCH_CONDITION, prefixStr, prefixStr, originNode); // retrieve all Strings that extend the _transition path denoted by // prefixString } } return strHashSet; }
@Override public boolean load(ByteArray byteArray) { int length = byteArray.nextInt(); for (int i = 0; i < length; ++i) { charTreeSet.add(byteArray.nextChar()); } simplifiedSourceNode = new SimpleMDAGNode(); simplifiedSourceNode.load(byteArray); length = byteArray.nextInt(); mdagDataArray = new SimpleMDAGNode[length]; for (int i = 0; i < length; ++i) { mdagDataArray[i] = new SimpleMDAGNode(); mdagDataArray[i].load(byteArray); } sourceNode = null; return true; }
/** * 递归创建节点<br> * * @param current 当前简易节点 * @param fromIndex 起点下标 * @param toNodeArray 终点数组 * @param fromNodeArray 起点数组,它们两个按照下标一一对应 */ private void createMDAGNode( SimpleMDAGNode current, int fromIndex, MDAGNode[] toNodeArray, MDAGNode[] fromNodeArray) { MDAGNode from = (fromIndex == -1 ? sourceNode : toNodeArray[fromIndex]); int transitionSetBegin = current.getTransitionSetBeginIndex(); int onePastTransitionSetEnd = transitionSetBegin + current.getOutgoingTransitionSetSize(); for (int i = transitionSetBegin; i < onePastTransitionSetEnd; i++) { SimpleMDAGNode targetNode = mdagDataArray[i]; if (toNodeArray[i] != null) { fromNodeArray[fromIndex].addOutgoingTransition(current.getLetter(), fromNodeArray[i]); toNodeArray[fromIndex] = fromNodeArray[i]; continue; } toNodeArray[i] = from.addOutgoingTransition(targetNode.getLetter(), targetNode.isAcceptNode()); fromNodeArray[i] = from; createMDAGNode(targetNode, i, toNodeArray, fromNodeArray); } }