public PrefixTree(int minimumPrefixLength) { InitBlock(); root = new PrefixTreeNode(new char[0]); this.minimumPrefixLength = System.Math.Max(minimumPrefixLength++, 0); this.minimumHeuristicLength = System.Math.Max((int)(minimumPrefixLength / 2), 3); }
public virtual void addChild(PrefixTreeNode node) { if (children == null) { children = new List <PrefixTreeNode>(); } children.addElement(node); node.parent = this; }
public void addString(String s) { PrefixTreeNode current = root; while (s.Length > 0) { int len = 0; PrefixTreeNode node = null; if (current.children != null) { for (IEnumerator e = current.children.GetEnumerator(); e.MoveNext();) { node = (PrefixTreeNode)e; len = sharedPrefixLength(s, node.prefix); if (len > 0) { break; } node = null; } } if (node == null) { node = new PrefixTreeNode(s); len = s.Length; if (current.children == null) { current.children = new ArrayList(); } current.children.Add(node); } else if (len < node.prefix.Length) { String prefix = s.Substring(0, len); PrefixTreeNode interimNode = new PrefixTreeNode(prefix); current.children.Remove(node); node.prefix = node.prefix.Substring(len); current.children.Add(interimNode); interimNode.children = new ArrayList(); interimNode.children.Add(node); node = interimNode; } current = node; s = s.Substring(len); } current.terminal = true; }
public virtual PrefixTreeNode budChild(PrefixTreeNode node, char[] subPrefix, int subPrefixLen) { //make a new child for the subprefix PrefixTreeNode newChild = new PrefixTreeNode(subPrefix); //remove the child from our tree (we'll re-add it later) this.children.removeElement(node); node.parent = null; //cut out the middle part of the prefix (which is now this node's domain) char[] old = node.prefix; node.prefix = new char[old.Length - subPrefixLen]; for (int i = 0; i < old.Length - subPrefixLen; ++i) { node.prefix[i] = old[subPrefixLen + i]; } //replace the old child with the new one, and put it in the proper order this.addChild(newChild); newChild.addChild(node); return(newChild); }
public PrefixTree() { root = new PrefixTreeNode(""); }
public virtual PrefixTreeNode addString(System.String newString) { if (finalized) { throw new System.SystemException("Can't manipulate a finalized Prefix Tree"); } if (disablePrefixing) { PrefixTreeNode newNode = new PrefixTreeNode(newString.ToCharArray()); newNode.setTerminal(); root.addChild(newNode); return(newNode); } PrefixTreeNode current = root; char[] chars = newString.ToCharArray(); int currentIndex = 0; while (currentIndex < chars.Length) { //The length of the string we've incorporated into the tree int len = 0; //The (potential) next node in the tree which prefixes the rest of the string PrefixTreeNode node = null; //TODO: This would be way faster if we sorted upon insertion.... if (current.getChildren() != null) { //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" for (System.Collections.IEnumerator e = current.getChildren().elements(); e.MoveNext();) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" node = (PrefixTreeNode)e.Current; char[] prefix = node.Prefix; //if(prefix.equals(s)) { if (ArrayUtilities.arraysEqual(prefix, 0, chars, currentIndex)) { return(node); } len = sharedPrefixLength(chars, currentIndex, prefix); if (len > minimumPrefixLength) { //See if we have any breaks which might make more heuristic sense than simply grabbing the biggest //difference for (char c: delimiters) { int sepLen = -1; for (int i = currentIndex + len - 1; i >= currentIndex; i--) { if (chars[i] == c) { sepLen = i - currentIndex; break; } } if (sepLen != -1 && len - sepLen < delSacrifice && sepLen > minimumHeuristicLength) { len = sepLen; break; } } break; } node = null; } } //If we didn't find anything that shared any common roots if (node == null) { //Create a placeholder for the rest of the string char[] newArray; if (currentIndex == 0) { newArray = chars; } else { newArray = new char[chars.Length - currentIndex]; for (int i = 0; i < chars.Length - currentIndex; ++i) { newArray[i] = chars[i + currentIndex]; } } node = new PrefixTreeNode(newArray); len = chars.Length - currentIndex; //Add this to the highest level prefix we've found current.addChild(node); } //Otherwise check to see if we are going to split the current prefix else if (len < node.Prefix.Length) { char[] newPrefix = new char[len]; for (int i = 0; i < len; ++i) { newPrefix[i] = chars[currentIndex + i]; } PrefixTreeNode interimNode = current.budChild(node, newPrefix, len); node = interimNode; } current = node; currentIndex = currentIndex + len; } current.setTerminal(); return(current); }
public virtual void clear() { finalized = false; root = new PrefixTreeNode(new char[0]); }