/** * Copyright © 2010-2012 Atilika Inc. All rights reserved. * * Atilika Inc. licenses this file to you under the Apache License, Version * 2.0 (the "License"); you may not use this file except in compliance with * the License. A copy of the License is distributed with this work in the * LICENSE.txt file. You may also obtain a copy of the License from * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.atilika.kuromoji.trie; /** * Normal Trie which is used to build DoubleArrayTrie * * @author Masaru Hasegawa * @author Christian Moen */ public class Trie { private Node root;// Root node of Trie /** * Constructor * Initialize Trie with empty root node */ public Trie() { root = new Node(); } /** * Add input value into Trie * Before adding, it adds terminating character(\u0001) to input string * @param value String to add to Trie */ public void add(String value) { root.add(value + DoubleArrayTrie.TERMINATING_CHARACTER); } /** * Return root node which contains other nodes * @return Node */ public Node getRoot() { return root; } /** * Trie Node */ public class Node { char key; // key(char) of this node Node[] children = new Node[0]; // Array to hold children nodes /** * Constructor */ public Node() { } /** * Constructor * @param key key for this node */ public Node(char key) { this.key = key; } /** * Add string to Trie * @param value String to add */ public void add(String value) { if (value.length() == 0) { return; } Node node = new Node(value.charAt(0)); addChild(node).add(value.substring(1)); } /** * Add Node to this node as child * @param newNode node to add * @return added node. If a node with same key already exists, return that node. */ public Node addChild(Node newNode) { Node child = getChild(newNode.getKey()); if (child == null) { Node[] newChildren = new Node[children.length + 1]; System.arraycopy(children, 0, newChildren, 0, children.length); newChildren[newChildren.length -1] = newNode; children = newChildren; child = newNode; } return child; } /** * Return the key of the node * @return key */ public char getKey() { return key; } /** * Check if children following this node has only single path. * For example, if you have "abcde" and "abfgh" in Trie, calling this method on node "a" and "b" returns false. * Calling this method on "c", "d", "e", "f", "g" and "h" returns true. * @return true if it has only single path. false if it has multiple path. */ public boolean hasSinglePath() { switch(children.length){ case 0: return true; case 1: return children[0].hasSinglePath(); default: return false; } } /** * Return children node * @return Array of children nodes */ public Node[] getChildren() { return children; } /** * Return node which has input key * @param key key to look for * @return node which has input key. null if it doesn't exist. */ private Node getChild(char key) { for (Node child : children) { if (child.getKey() == key) { return child; } } return null; } } }