All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.nlp.ling.tokensregex.matcher.TrieMap Maven / Gradle / Ivy

Go to download

Stanford CoreNLP provides a set of natural language analysis tools which can take raw English language text input and give the base forms of words, their parts of speech, whether they are names of companies, people, etc., normalize dates, times, and numeric quantities, mark up the structure of sentences in terms of phrases and word dependencies, and indicate which noun phrases refer to the same entities. It provides the foundational building blocks for higher level text understanding applications.

There is a newer version: 4.5.7
Show newest version
package edu.stanford.nlp.ling.tokensregex.matcher;

import edu.stanford.nlp.util.Generics;
import edu.stanford.nlp.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Map that takes a iterable as key, and maps it to an value.
 *
 * This implementation is not particularly memory efficient, but will have relatively
 * fast lookup times for sequences where there are many possible keys (e.g. sequences over Strings).
 * Can be used for fairly efficient look up of sequence by prefix.
 *
 * @author Angel Chang
 *
 * @param  Key of the elements of the trie
 * @param  The value
 *
 */
public class TrieMap extends AbstractMap, V> {

  /**
   * Child tries
   */
  protected Map> children;

  /**
   * Value at a leaf node (leaf node is indicated by non-null value)
   */
  protected V value;
  // Should we have explicit marking if this element is a leaf node without requiring value?

  public TrieMap() {
  }

  public TrieMap(int initialCapacity) {
    // TODO: initial capacity implementation
  }

  // Trie specific functions
  public TrieMap getChildTrie(K key) {
    return (children != null)? children.get(key):null;
  }

  public TrieMap getChildTrie(Iterable key) {
    TrieMap curTrie = this;
    // go through each element
    for (K element : key){
      curTrie = (curTrie.children != null)? curTrie.children.get(element):null;
      if (curTrie == null) {
        return null;
      }
    }
    return curTrie;
  }

  public TrieMap putChildTrie(Iterable key, TrieMap child) {
    TrieMap parentTrie = null;
    TrieMap curTrie = this;
    Iterator keyIter = key.iterator();
    // go through each element
    while (keyIter.hasNext()) {
      K element = keyIter.next();
      boolean isLast = !keyIter.hasNext();
      if (curTrie.children == null) {
        curTrie.children = new ConcurrentHashMap<>();//Generics.newConcurrentHashMap();
      }
      parentTrie = curTrie;
      curTrie = curTrie.children.get(element);
      if (isLast) {
        parentTrie.children.put(element, child);
      } else if(curTrie == null){
        parentTrie.children.put(element, curTrie = new TrieMap<>());
      }
    }
    if (parentTrie == null) {
      throw new IllegalArgumentException("Cannot put a child trie with no keys");
    }
    return curTrie;
  }

  public Map> getChildren() {
    return children;
  }

  public V getValue() {
    return value;
  }

  public boolean isLeaf() {
    return value != null;
  }


  public String toFormattedString() {
    List strings = new LinkedList<>();
    updateTrieStrings(strings, "");
    return StringUtils.join(strings, "\n");
  }

  protected void updateTrieStrings(List strings, String prefix) {
    if (children != null) {
      for (Entry> kTrieMapEntry : children.entrySet()) {
        kTrieMapEntry.getValue().updateTrieStrings(strings, prefix + " - " + kTrieMapEntry.getKey());
      }
    }
    if (isLeaf()) {
      strings.add( prefix + " -> " + value);
    }
  }

  // Functions to support map interface to lookup using sequence

  @Override
  public int size() {
    int s = 0;
    if (children != null) {
      for (Entry> kTrieMapEntry : children.entrySet()) {
        s += kTrieMapEntry.getValue().size();
      }
    }
    if (isLeaf()) s++;
    return s;
  }

  @Override
  public boolean isEmpty() {
    return (children == null && !isLeaf());
  }

  @Override
  public boolean containsKey(Object key) {
    return get(key) != null;
  }

  @Override
  public boolean containsValue(Object value) {
    return values().contains(value);
  }

  @Override
  public V get(Object key) {
    if (key instanceof Iterable) {
      return get( (Iterable) key);
    } else if (key instanceof Object[]) {
      return get( Arrays.asList( (Object[]) key) );
    }
    return null;
  }

  public V get(Iterable key) {
    TrieMap curTrie = getChildTrie(key);
    return (curTrie != null) ? curTrie.value: null;
  }

  public V get(K[] key) {
    return get(Arrays.asList(key));
  }

  @Override
  public V put(Iterable key, V value) {
    if (value == null) throw new IllegalArgumentException("Value cannot be null");
    TrieMap curTrie = this;
    // go through each element
    for(K element:key){
      if (curTrie.children == null) {
        curTrie.children = new ConcurrentHashMap<>();//Generics.newConcurrentHashMap();
      }
      TrieMap parent = curTrie;
      curTrie = curTrie.children.get(element);
      if(curTrie == null){
        parent.children.put(element, curTrie = new TrieMap<>());
      }
    }
    V oldValue = curTrie.value;
    curTrie.value = value;
    return oldValue;
  }

  public V put(K[] key, V value) {
    return put(Arrays.asList(key), value);
  }

  @Override
  public V remove(Object key) {
    if (key instanceof Iterable) {
      return remove( (Iterable) key );
    }
    return null;
  }

  public V remove(Iterable key) {
    TrieMap parent = null;
    TrieMap curTrie = this;
    Object lastKey = null;
    // go through each element
    for(Object element : key){
      if (curTrie.children == null) return null;
      lastKey = element;
      parent = curTrie;
      curTrie = curTrie.children.get(element);
      if (curTrie == null){
        return null;
      }
    }
    V v = curTrie.value;
    if (parent != null) {
      parent.children.remove(lastKey);
    } else {
      value = null;
    }
    return v;
  }

  public V remove(K[] key) {
    return remove(Arrays.asList(key));
  }

  @Override
  public void putAll(Map, ? extends V> m) {
    for (Entry, ? extends V> entry : m.entrySet()) {
      put(entry.getKey(), entry.getValue());
    }
  }

  @Override
  public void clear() {
    value = null;
    children = null;
  }

  @Override
  public Set> keySet() {
    Set> keys = new LinkedHashSet<>();
    updateKeys(keys, new ArrayList<>());
    return keys;
  }

  protected void updateKeys(Set> keys, List prefix) {
    if (children != null) {
      for (Entry> kTrieMapEntry : children.entrySet()) {
        List p = new ArrayList<>(prefix.size() + 1);
        p.addAll(prefix);
        p.add(kTrieMapEntry.getKey());
        kTrieMapEntry.getValue().updateKeys(keys, p);
      }
    }
    if (value != null) {
      keys.add(prefix);
    }
  }

  @Override
  public Collection values() {
    List values = new ArrayList<>();
    updateValues(values);
    return values;
  }

  protected void updateValues(List values) {
    if (children != null) {
      for (Entry> kTrieMapEntry : children.entrySet()) {
        kTrieMapEntry.getValue().updateValues(values);
      }
    }
    if (value != null) {
      values.add(value);
    }
  }

  @Override
  public Set, V>> entrySet() {
    Set, V>> entries = new LinkedHashSet<>();
    updateEntries(entries, new ArrayList<>());
    return entries;
  }

  protected void updateEntries(Set,V>> entries, final List prefix) {
    if (children != null) {
      for (Entry> kTrieMapEntry : children.entrySet()) {
        List p = new ArrayList<>(prefix.size() + 1);
        p.addAll(prefix);
        p.add(kTrieMapEntry.getKey());
        kTrieMapEntry.getValue().updateEntries(entries, p);
      }
    }
    if (value != null) {
      entries.add(new Map.Entry,V>() {
        @Override
        public Iterable getKey() {
          return prefix;
        }

        @Override
        public V getValue() {
          return value;
        }

        @Override
        public V setValue(V value) {
          throw new UnsupportedOperationException();
        }
      });
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy