Norway


#include <iostream>

#include <vector>

#include <unordered_map>

#include <unordered_set>

#include <algorithm>

using namespace std;

 

// define maximum number of in the

#define N 100

 

// Data structure to store graph edges

struct Edge {

    int src, dest;

};

 

// Class to represent a graph object

class Graph

{

public:    

    // construct a vector of vectors to represent an adjacency list

    vector<unordered_set<int>> adjList;

 

    // Graph Constructor

    Graph()

    {

        // resize the vector to N elements of type unordered_set<int>

        adjList.resize(N);

    }

};

 

// Perform DFS on graph and set departure of all vertices of the graph

void DFS(Graph const &graph, int v, vector<bool>

    &discovered, vector<int> &departure, int& time)

{

    // mark current node as discovered

    discovered[v] = true;

 

    // set arrival time

    time++;

 

    // do for every edge (v -> u)

    for (int u : graph.adjList[v])

    {

        // u is not discovered

        if (!discovered[u]) {

            DFS(graph, u, discovered, departure, time);

        }

    }

    

    // ready to backtrack

    // set departure time of vertex v

    departure[time] = v;

    time++;

}

 

// Utility function to performs Topological Sort on a given DAG

void doTopologicalSort(Graph const& graph, unordered_map<int,string> &map)

{

    // departure[] stores the vertex number using departure time as index

    vector<int> departure(2*N, 1);

    

    // Note if we had done the other way around i.e.

    // fill the array with departure time by using vertex number

    // as index, we would need to sort the array later

 

    // stores vertex is discovered or not

    vector<bool> discovered(N);

    int time = 0;

 

    // perform DFS on all undiscovered vertices

    for (int i = 0; i < N; i++) {

        if (!discovered[i] && graph.adjList[i].size() != 0) {

            DFS(graph, i, discovered, departure, time);

        }

    }

 

    cout << “The order of alphabets in the ancient language are: “;

 

    // Print the vertices in order of their decreasing

    // departure time in DFS i.e. in topological order

    for (int i = 2*N 1; i >= 0; iR;) {

        if (departure[i] != 1) {

            cout << map[departure[i]] << ” “;

        }

    }

}

 

// Utility function to print adjacency list representation of graph

void printGraph(Graph const& graph, unordered_map<int,string> &map)

{

    for (int i = 0; i < N; i++)

    {

        // ignore vertices with no outgoing edges

        if (graph.adjList[i].size() != 0)

        {

            // print current vertex

            cout << map[i] << ” –> “;

 

            // print all neighboring vertices of vertex i

            for (int v : graph.adjList[i])

                cout << map[v] << ” “;

    

            cout << endl;

        }

    }

    cout << endl;

}

 

// Utility function to construct an inverse map from the original map to do

// the reverse lookup in constant time

template<typename K, typename V>

std::unordered_map<V,K> inverse_map(std::unordered_map<K,V> &map)

{

    std::unordered_map<V,K> inv;

    std::for_each(map.begin(), map.end(),

                [&inv] (const std::pair<K,V> &p)

                {

                    inv.insert(std::make_pair(p.second, p.first));

                });

    return inv;

}

 

// Function to the correct order of alphabets in a given dictionary of

// ancient . This function assumes that the input is correct.

void findDictinaryAlphabetsOrder(vector<vector<string>>& dict)

{

    // create an unordered_map to map each non-ascii character present in the

    // given dictionary with an unique integer

    unordered_map<string, int> map;

 

    int k = 0;

    

    // do for each word

    for (auto word: dict)

    {

        // do for each non-ascii character of the word

        for (string s: word)

        {

            // if current character is not present in the map, insert it

            if (map.find(s) == map.end()) {

                map[s] = k++;

            }

        }

    }

    

    // create a graph containing N nodes

    Graph graph;

 

    // iterate through the complete dictionary and compare adjacent words

    // for character mismatch

    for (int i = 1; i < dict.size(); i++)

    {

        // previous word in the dictionary

        auto prev = dict[i1];

 

        // current word in the dictionary

        auto curr = dict[i];

 

        // iterate through both ‘prev’ and ‘curr’ simultaneously and find the

        // first mismatching character

        for (int j = 0; j < prev.size() && j < curr.size(); j++)

        {

            // mismatch found

            if (prev[j] != curr[j])

            {

                // add an edge from current character of ‘prev’ to

                // current character of ‘curr’ in the graph

                graph.adjList[map[prev[j]]].insert(map[curr[j]]);

                break;

            }

        }

    }

 

    // create a reverse map

    unordered_map<int,string> reverse = inverse_map(map);

 

    // printGraph(graph, reverse);

 

    // perform topological sort on the above graph

    doTopologicalSort(graph, reverse);

}

 

int main()

{

    // ancient dictionary containing words ¥€±, €±€, €±‰ð, ðß, ±±ð, ±ßß

    // individual characters of each word are stored as string since

    // they are non-ASCII

    vector<vector<string>> dict

                            {

                                {“¥”, “€”, “±”},

                                {“€”, “±”, “€”},

                                {“€”, “±”, “‰”, “ð”},

                                {“ð”, “ß”},

                                {“±”, “±”, “ð”},

                                {“±”, “ß”, “ß”}

                            };

 

    findDictinaryAlphabetsOrder(dict);

 

    return 0;

}



Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here