/** * Returns the number of successor for a node. If the node could not be found the return value is * 0. * * @param aWord a word. * @return the number of successor for a node. */ public Integer getSuccessors(String aWord) { KeyValueNode<String, Integer> node = findWord(aWord); if (node != null) { return node.getValue(); } return 0; }
/** * Finds a node with a given string. If not found NULL is returned. * * @param aWord a word. * @return a node with a given string or {@code null}. */ public KeyValueNode<String, Integer> findWord(String aWord) { aWord = aWord.toLowerCase(); KeyValueNode<String, Integer> parent = root; int depth = 1; while (parent.hasChildren()) { String w = aWord.substring(0, depth); KeyValueNode<String, Integer> child = parent.getChild(w); if (w.equals(aWord)) { return child; } else if (child != null) { parent = child; depth++; } else { return null; } } return null; }
/** * Adds a word to the tree. Also increments the successor value for each node * * @param aWord a word. */ public void addWord(String aWord) { KeyValueNode<String, Integer> parent = root; for (int i = 0; i < aWord.length(); i++) { String subword = aWord.substring(0, i + 1); KeyValueNode<String, Integer> child = parent.getChild(subword); if (child != null) { if (!subword.equals(aWord)) { child.setValue(child.getValue() + 1); } } else { Integer value = 1; if (subword.equals(aWord)) { value = 0; } child = new KeyValueNode<String, Integer>(subword, value); parent.addChild(child); } parent = child; } }
private V put(ArrayNode parent, Node node, byte height, int key, V value) { if (node instanceof KeyValueNode) { KeyValueNode<V> kvNode = (KeyValueNode<V>) node; if (key == kvNode.key) { // Key already exists as key-value pair, replace value kvNode.value = value; return value; } // Key already exists but doesn't match current key KeyValueNode<V> oldParent = kvNode; int newParentPosition = getPosition(height - 1, key); int oldParentPosition = getPosition(height, oldParent.key); int childPosition = getPosition(height, key); ArrayNode newParent = new ArrayNode(parent, key, height); newParent.parent = parent; if (parent == null) { // Only the root doesn't have a parent, so new root root = newParent; } else { // Add the child to the parent in it's parent's position parent.addChild(newParentPosition, newParent); } if (oldParentPosition != childPosition) { // The easy case, the two children have different positions in parent newParent.addChild(oldParentPosition, oldParent); oldParent.parent = newParent; newParent.addChild(childPosition, new KeyValueNode<V>(newParent, key, value)); return null; } while (oldParentPosition == childPosition) { // Handle the case when the new children map to same position. height++; if (height > MAX_DEPTH) { // We have found two keys which match exactly. System.err.println("Yikes! Found two keys which match exactly."); return null; } newParentPosition = getPosition(height - 1, key); ArrayNode newParent2 = new ArrayNode(newParent, key, height); newParent.addChild(newParentPosition, newParent2); oldParentPosition = getPosition(height, oldParent.key); childPosition = getPosition(height, key); if (oldParentPosition != childPosition) { newParent2.addChild(oldParentPosition, oldParent); oldParent.parent = newParent2; newParent2.addChild(childPosition, new KeyValueNode<V>(newParent2, key, value)); } else { newParent = newParent2; } } return null; } else if (node instanceof ArrayNode) { ArrayNode arrayRoot = (ArrayNode) node; int position = getPosition(arrayRoot.height, key); Node child = arrayRoot.getChild(position); if (child == null) { // Found an empty slot in parent arrayRoot.addChild(position, new KeyValueNode<V>(arrayRoot, key, value)); return null; } return put(arrayRoot, child, (byte) (height + 1), key, value); } return null; }