Wednesday, November 11, 2015

Find out order between characters from given dictionary words

Given a dictionary of unknown language and characters. Find out order between characters.
Example : "ab", "bbd", "bed", "bcd", "ce", "de"
Output : a, b, e, c, d

Finding out the sorting order using brute force would be tedious task. We can use topological sorting for this.

We will create a graph having characters as node in graph and have edge between two character if any character appear next to other character. 

Solution below implements full topological sorting approach, where we create a graph and then search the character order using topological sorting.
Graph uses adjacency list implementation.

class Graph{
    int V;
    int vCnt;

    class Node{
        public char data;
        public Node next;

        public Node(char ch, Node nxt){
            data = ch;
            next = nxt;
        }
    }

    Node[] adj;

    public Graph(int v){
        V = v;
        vCnt = 0;
        adj = new Node[v];
    }

    public void AddEdge(char v, char w){
        Node n = SearchNode(v);
        while (n.next != null){
            if(n.next.data == w)
                return;
            n = n.next;
        }
        n.next = new Node(w, null);
        Node m = SearchNode(w);
    }

    private Node SearchNode(char ch){
        for (int i = 0; i < vCnt; i++){
            if(adj[i].data == ch){
                return adj[i];
            }
        }
        adj[vCnt] = new Node(ch, null);
        vCnt++;
        return adj[vCnt-1];
    }

    private void TopologicalUtil(char ch, HashMap visited, Stack stack){
        visited.put(ch, Boolean.TRUE);
        Node n = SearchNode(ch);
        while (n.next != null){
            if(visited.get(n.next.data) == Boolean.FALSE )
                TopologicalUtil(n.next.data, visited, stack);
            n = n.next;
        }
        stack.push(ch);
    }

    public void TopologicalSort(){
        Stack stack = new Stack();
        HashMap visited = new HashMap();
        for(int i = 0; i < vCnt; i++ ){
            visited.put(adj[i].data,Boolean.FALSE);
        }

        for(int i = 0; i < vCnt; i++ ){
            if(visited.get(adj[i].data) == Boolean.FALSE )
                TopologicalUtil(adj[i].data, visited, stack);
        }

        while (!stack.isEmpty()){
            System.out.print(stack.pop() + ", ");
        }
    }
}

public class Solution{

    public static void main(String[] args) {
        List input = new ArrayList<>();
        input.add("ab");
        input.add("bbd");
        input.add("bed");
        input.add("bcd");
        input.add("ce");
        input.add("de");

        Graph g = new Graph(5);

        for (int i = 0; i < input.size()-1; i++) {
            String str = input.get(i);
            String str2 = input.get(i+1);
            if(str.charAt(0) != str2.charAt(0)) {
                char v = str.charAt(0);
                char w = str2.charAt(0);
                g.AddEdge(v, w);
            }
        }

        for (int i = 0; i < input.size()-1; i++){
            String str = input.get(i);
            String str2 = input.get(i+1);
            if(str.charAt(0) == str2.charAt(0)) {
                for (int j = 1; j < Math.min(str.length(), str2.length()); j++) {
                    if(str.charAt(j) != str2.charAt(j)) {
                        char v = str.charAt(j);
                        char w = str2.charAt(j);
                        g.AddEdge(v, w);
                    }
                }
            }
        }

        g.TopologicalSort();
    }
}

Problem referenced from geeksforgeeks.

No comments:

Post a Comment