Wednesday, 2 August 2017

CTCI Challange, DAY 9

Day 9:- 
Problem statement:Tries: Contacts

Note:-
Updated version below..
 
Tries is new concept,I gone through the Princeton algorithms lectures and got a picture of what this data structure is all about.

Implemented the logic using the existing algorithms given by Princeton.

import java.util.*;

/**
 * @author vikram.shanbogar@gmail.com
 * on 8/2/2017.
 */
public class Tries<Value> {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        TrieST<Integer> tries = new TrieST();
        List<Integer> list = new ArrayList<>();
        for (int a0 = 0; a0 < n; a0++) {
            String op = in.next();
            String contact = in.next();
            if (op.equals("add")) {
                tries.put(contact, a0);
            }
            if (op.equals("find")) {
                int count = 0;
                for (Object s : tries.keysWithPrefix(contact))
                    count++;
                System.out.println(count);
            }
        }
    }

    public static class TrieST<Value> {
        private static final int R = 256;        // extended ASCII


        private Node root;      // root of trie
        private int n;          // number of keys in trie

        // R-way trie node
        private static class Node {
            private Object val;
            private Node[] next = new Node[R];
        }

        /**
         * Initializes an empty string symbol table.
         */
        public TrieST() {
        }


        /**
         * Returns the value associated with the given key.
         *
         * @param key the key
         * @return the value associated with the given key if the key is in the symbol table
         * and {@code null} if the key is not in the symbol table
         * @throws IllegalArgumentException if {@code key} is {@code null}
         */
        public Value get(String key) {
            if (key == null) throw new IllegalArgumentException("argument to get() is null");
            Node x = get(root, key, 0);
            if (x == null) return null;
            return (Value) x.val;
        }

        /**
         * Does this symbol table contain the given key?
         *
         * @param key the key
         * @return {@code true} if this symbol table contains {@code key} and
         * {@code false} otherwise
         * @throws IllegalArgumentException if {@code key} is {@code null}
         */
        public boolean contains(String key) {
            if (key == null) throw new IllegalArgumentException("argument to contains() is null");
            return get(key) != null;
        }

        private Node get(Node x, String key, int d) {
            if (x == null) return null;
            if (d == key.length()) return x;
            char c = key.charAt(d);
            return get(x.next[c], key, d + 1);
        }

        /**
         * Inserts the key-value pair into the symbol table, overwriting the old value
         * with the new value if the key is already in the symbol table.
         * If the value is {@code null}, this effectively deletes the key from the symbol table.
         *
         * @param key the key
         * @param val the value
         * @throws IllegalArgumentException if {@code key} is {@code null}
         */
        public void put(String key, Value val) {
            if (key == null) throw new IllegalArgumentException("first argument to put() is null");
            if (val == null) delete(key);
            else root = put(root, key, val, 0);
        }

        private Node put(Node x, String key, Value val, int d) {
            if (x == null) x = new Node();
            if (d == key.length()) {
                if (x.val == null) n++;
                x.val = val;
                return x;
            }
            char c = key.charAt(d);
            x.next[c] = put(x.next[c], key, val, d + 1);
            return x;
        }

        /**
         * Returns the number of key-value pairs in this symbol table.
         *
         * @return the number of key-value pairs in this symbol table
         */
        public int size() {
            return n;
        }

        /**
         * Is this symbol table empty?
         *
         * @return {@code true} if this symbol table is empty and {@code false} otherwise
         */
        public boolean isEmpty() {
            return size() == 0;
        }

        /**
         * Returns all keys in the symbol table as an {@code Iterable}.
         * To iterate over all of the keys in the symbol table named {@code st},
         * use the foreach notation: {@code for (Key key : st.keys())}.
         *
         * @return all keys in the symbol table as an {@code Iterable}
         */
        public Iterable<String> keys() {
            return keysWithPrefix("");
        }

        /**
         * Returns all of the keys in the set that start with {@code prefix}.
         *
         * @param prefix the prefix
         * @return all of the keys in the set that start with {@code prefix},
         * as an iterable
         */
        public Iterable<String> keysWithPrefix(String prefix) {
            Queue<String> results = new PriorityQueue<>();
            Node x = get(root, prefix, 0);
            collect(x, new StringBuilder(prefix), results);
            return results;
        }

        private void collect(Node x, StringBuilder prefix, Queue<String> results) {
            if (x == null) return;
            if (x.val != null) results.offer(prefix.toString());
            for (char c = 0; c < R; c++) {
                prefix.append(c);
                collect(x.next[c], prefix, results);
                prefix.deleteCharAt(prefix.length() - 1);
            }
        }

        /**
         * Returns all of the keys in the symbol table that match {@code pattern},
         * where . symbol is treated as a wildcard character.
         *
         * @param pattern the pattern
         * @return all of the keys in the symbol table that match {@code pattern},
         * as an iterable, where . is treated as a wildcard character.
         */
        public Iterable<String> keysThatMatch(String pattern) {
            Queue<String> results = new PriorityQueue<>();
            collect(root, new StringBuilder(), pattern, results);
            return results;
        }

        private void collect(Node x, StringBuilder prefix, String pattern, Queue<String> results) {
            if (x == null) return;
            int d = prefix.length();
            if (d == pattern.length() && x.val != null)
                results.offer(prefix.toString());
            if (d == pattern.length())
                return;
            char c = pattern.charAt(d);
            if (c == '.') {
                for (char ch = 0; ch < R; ch++) {
                    prefix.append(ch);
                    collect(x.next[ch], prefix, pattern, results);
                    prefix.deleteCharAt(prefix.length() - 1);
                }
            } else {
                prefix.append(c);
                collect(x.next[c], prefix, pattern, results);
                prefix.deleteCharAt(prefix.length() - 1);
            }
        }

        /**
         * Returns the string in the symbol table that is the longest prefix of {@code query},
         * or {@code null}, if no such string.
         *
         * @param query the query string
         * @return the string in the symbol table that is the longest prefix of {@code query},
         * or {@code null} if no such string
         * @throws IllegalArgumentException if {@code query} is {@code null}
         */
        public String longestPrefixOf(String query) {
            if (query == null) throw new IllegalArgumentException("argument to longestPrefixOf() is null");
            int length = longestPrefixOf(root, query, 0, -1);
            if (length == -1) return null;
            else return query.substring(0, length);
        }

        // returns the length of the longest string key in the subtrie
        // rooted at x that is a prefix of the query string,
        // assuming the first d character match and we have already
        // found a prefix match of given length (-1 if no such match)
        private int longestPrefixOf(Node x, String query, int d, int length) {
            if (x == null) return length;
            if (x.val != null) length = d;
            if (d == query.length()) return length;
            char c = query.charAt(d);
            return longestPrefixOf(x.next[c], query, d + 1, length);
        }

        /**
         * Removes the key from the set if the key is present.
         *
         * @param key the key
         * @throws IllegalArgumentException if {@code key} is {@code null}
         */
        public void delete(String key) {
            if (key == null) throw new IllegalArgumentException("argument to delete() is null");
            root = delete(root, key, 0);
        }

        private Node delete(Node x, String key, int d) {
            if (x == null) return null;
            if (d == key.length()) {
                if (x.val != null) n--;
                x.val = null;
            } else {
                char c = key.charAt(d);
                x.next[c] = delete(x.next[c], key, d + 1);
            }

            // remove subtrie rooted at x if it is completely empty
            if (x.val != null) return x;
            for (int c = 0; c < R; c++)
                if (x.next[c] != null)
                    return x;
            return null;
        }
    }
}

Note:- updated on 22/8/17
Today got time to work on CTCI backlogs.Completed the tries problem.

package vikram.HR;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

class TrieNode1 {
    char c;
    HashMap<Character, TrieNode1> children = 
            new HashMap<Character, TrieNode1>();
    boolean isLeaf;
    public int size;

    public TrieNode1() {
    }

    public TrieNode1(char c) {
        this.c = c;
    }
}

class Trie {
    private TrieNode1 root = new TrieNode1();

    public void insert(String word) {
        HashMap<Character, TrieNode1> children = root.children;

        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);

            TrieNode1 t;
            if (children.containsKey(c)) {
                t = children.get(c);
            } else {
                t = new TrieNode1(c);
                children.put(c, t);
            }

            children = t.children;

            //set leaf node            if (i == word.length() - 1)
                t.isLeaf = true;
            t.size++;
        }
    }

    // Returns if the word is in the trie.    
public boolean search(String word) {
        TrieNode1 t = searchNode(word);

        if (t != null && t.isLeaf)
            return true;
        else            return false;
    }

    // Returns if there is any word in the trie    
// that starts with the given prefix.   
       public int startsWith(String prefix) {
        TrieNode1 val = searchNode(prefix);
        if (val == null)
            return 0;
        else            return val.size;
    }

    public TrieNode1 searchNode(String str) {
        Map<Character, TrieNode1> children = 
                root.children;
        TrieNode1 t = null;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (children.containsKey(c)) {
                t = children.get(c);
                children = t.children;
            } else {
                return null;
            }
        }

        return t;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Trie t = new Trie();
        for (int a0 = 0; a0 < n; a0++) {
            String op = in.next();
            String contact = in.next();
            if (op.equals("add")) {
                t.insert(contact);
            } else {
                System.out.println(t.startsWith(contact));
            }
        }
    }
}

No comments:

Post a Comment

Installing Docker and Minikube

  install docker-   sudo apt install docker.io   set user to docker group:- sudo gpasswd -a   {user} docker   imp commands:- ...