Find alphabetical order such that words can be considered sorted in C++

C++Server Side ProgrammingProgramming

Suppose we have an array of words, we have to find any alphabetical order in the English alphabet so that the given words can be considered sorted in ascending order, if there is any such order exists, otherwise return "impossible".

So, if the input is like words = ["efgh", "wxyz"], then the output will be zyxvutsrqponmlkjihgfewdcba

To solve this, we will follow these steps −

  • ALPHABET := 26
  • n := size of v
  • if n is same as 1, then −
    • display "abcdefghijklmnopqrstuvwxyz"
    • return
  • Define an array adj of size ALPHABET
  • Define an array in of size ALPHABET and fill with 0
  • pre := v[0]
  • for initialize i := 1, when i < n, update (increase i by 1), do −
    • s := v[i]
    • for j in range 0 to minimum of (size of pre and size of s) - 1 −
      • if s[j] is not equal to pre[j], then −
        • Come out from the loop
      • if j < minimum of size of pre and size of s, then −
        • insert s[j] - ASCII of 'a' at the end of adj[pre[j] - ASCII of 'a']
      • increase in[s[j] - ASCII of 'a'] by 1
      • pre := s
      • Ignore following part, skip to the next iteration
    • if size of pre > size of s, then −
      • display "Impossible"
      • return
    • pre := s
  • Define one stack my_stack
  • for initialize i := 0, when i < ALPHABET, update (increase i by 1), do −
    • if in[i] is same as 0, then −
      • insert i into my_stack
    • Define an array out
  • Define an array vis of size: 26. fill with false
  • while (my_stack is not empty), do −
    • x := top element of my_stack
    • delete element from my_stack
    • vis[x] := true
    • insert x + ASCII of 'a' at the end of out
    • for initialize i := 0, when i < size of adj[x], update (increase i by 1), do −
      • if vis[adj[x, i]] is non-zero, then −
        • Ignore following part, skip to the next iteration
      • (decrease in[adj[x, i]] by 1)
      • if in[adj[x, i]] is same as 0, then −
        • insert adj[x, i] into my_stack
    • for initialize i := 0, when i < ALPHABET, update (increase i by 1), do −
      • if not vis[i] is non-zero, then −
        • display "Impossible"
      • return
    • for initialize i := 0, when i < size of out, update (increase i by 1), do −
      • display out[i]

Example 

Let us see the following implementation to get better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
#define ALPHABET 26
void search_ordering(vector<string> v) {
   int n = v.size();
   if (n == 1) {
      cout << "abcdefghijklmnopqrstuvwxyz";
      return;
   }
   vector<int> adj[ALPHABET];
   vector<int> in(ALPHABET, 0);
   string pre = v[0];
   for (int i = 1; i < n; ++i) {
      string s = v[i];
      int j;
      for (j = 0; j < min(pre.length(), s.length()); ++j)
         if (s[j] != pre[j])
            break;
      if (j < min(pre.length(), s.length())) {
         adj[pre[j] - 'a'].push_back(s[j] - 'a');
         in[s[j] - 'a']++;
         pre = s;
         continue;
      }
      if (pre.length() > s.length()) {
         cout << "Impossible";
         return;
      }
      pre = s;
   }
   stack<int> my_stack;
   for (int i = 0; i < ALPHABET; ++i)
      if (in[i] == 0)
         my_stack.push(i);
   vector<char> out;
   bool vis[26];
   memset(vis, false, sizeof(vis));
   while (!my_stack.empty()) {
      char x = my_stack.top();
      my_stack.pop();
      vis[x] = true;
      out.push_back(x + 'a');
      for (int i = 0; i < adj[x].size(); ++i) {
         if (vis[adj[x][i]])
            continue;
         in[adj[x][i]]--;
         if (in[adj[x][i]] == 0)
            my_stack.push(adj[x][i]);
      }
   }
   for (int i = 0; i < ALPHABET; ++i)
   if (!vis[i]) {
      cout << "Impossible";
      return;
   }
   for (int i = 0; i < out.size(); ++i)
   cout << out[i];
}
int main() {
   vector<string> v{"efgh", "wxyz"};
   search_ordering(v);
}

Input

{"efgh", "wxyz"}

Output

zyxvutsrqponmlkjihgfewdcba
raja
Published on 23-Jul-2020 09:06:28
Advertisements