Synonymous Sentences in C++



Suppose we have a list of pairs of equivalent words synonyms and a sentence text, we have to find all possible synonymous sentences they are sorted lexicographically.

So, if the input is like synonyms = [["happy","joy"],["sad","sorrow"],["joy","cheerful"]], and text = "I am happy today but was sad yesterday", then the output will be ["I am cheerful today but was sad yesterday", "I am cheerful today but was sorrow yesterday", "I am happy today but was sad yesterday", "I am happy today but was sorrow yesterday", "I am joy today but was sad yesterday", "I am joy today but was sorrow yesterday"]

To solve this, we will follow these steps −

  • Define maps parent, color and groupByColor

  • Define a function find(), this will take s,

  • if parent[s] is same as s, then −

    • parent[s] := find(parent[s])

  • return parent[s]

  • Define a function unionNode(), this will take a, b,

  • x := find(a), y := find(b)

  • if x is same as y, then −

    • parent[x] := y

  • Define an array ans

  • Define a function getString(), this will take t,

  • Define an array temp

  • end := 0

  • curr := blank string

  • for end < size of t, update (increase end by 1), do −

    • if t[end] is same as empty space, then −

      • insert curr at the end of temp

      • curr := blank string

      • Ignore following part, skip to the next iteration

    • curr := curr concatenate t[end]

  • insert curr at the end of temp

  • return temp

  • Define a function dfs(), this will take strings, idx, temp initialize it with blank string,

  • if idx is same as size of strings, then −

    • insert temp at the end of ans

    • return

  • current := strings[idx]

  • if current is not in color, then −

    • dfs(strings, idx + 1, temp + current concatenate ((if idx + 1 is same as size of strings, then blank string, otherwise blank space)))

  • Otherwise

    • Define one set x = groupByColor[color[current]]

    • for each element z in x, do −

      • dfs(strings, idx + 1, temp + z + ((if idx + 1 is same as size of strings, then blank string, otherwise blank space)))

      • (increase z by 1)

  • Define a function seeGroups()

  • for each element i in groupByColor, do −

    • x := second of i as set

    • Define one set

    • for each element z in x −

      • (increase i by 1)

  • Define a function generateSentences(), this will take one 2D array s, another string t,

  • n := size of s

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • x := s[i, 0]

    • y := s[i, 1]

    • if x is not in parent, then −

      • if y is not in parent, then −

        • unionNode(x, y)

  • c := 1

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • x := s[i, 0]

    • z := s[i, 1]

    • y := find(x)

    • if y is not in color, then −

      • color[y] := c

      • (increase c by 1)

    • color[x] := color[y]

    • color[z] := color[y]

    • if color[x] is not in groupByColor, then −

      • Define one set ss

      • insert x into ss

      • insert y into ss

      • groupByColor[color[x]] := ss

    • Otherwise

      • insert x into groupByColor[color[x]]

      • insert z into groupByColor[color[x]]

  • Define an array strings = getString(t)

  • dfs(strings, 0)

  • sort the array ans

  • return ans

Example 

Let us see the following implementation to get better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto< v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
class Solution {
public:
   map <string, string> parent;
   map <string, int> color;
   map <int, set<string<> groupByColor;
   string find(string s){
      if(parent[s] == s)return s;
         parent[s] = find(parent[s]);
      return parent[s];
   }
   void unionNode(string a, string b){
      string x = find(a);
      string y = find(b);
      if(x == y)return;
         parent[x] = y;
   }
   vector <string< ans;
   vector <string< getString(string t){
      vector <string< temp;
      int end = 0;
      string curr = "";
      for(;end < t.size(); end++){
         if(t[end] == ' '){
            temp.push_back(curr);
            curr = "";
            continue;
         }
         curr += t[end];
      }
      temp.push_back(curr);
      return temp;
   }
   void dfs(vector <string< &strings, int idx, string temp = ""){
      if(idx == strings.size()){
         ans.push_back(temp);
         return;
      }
      string current = strings[idx];
      if(color.find(current) == color.end()){
         dfs(strings, idx + 1, temp + current + (idx+1 == strings.size()?"":" "));
      }
      else{
         set <string< x = groupByColor[color[current]];
         set <string< :: iterator z = x.begin();
         while(z != x.end()){
            dfs(strings, idx + 1, temp + *z + (idx+1 == strings.size()?"":" "));
            z++;
         }
      }
   }
   void seeGroups(){
      map <int, set <string< > :: iterator i = groupByColor.begin();
      while(i != groupByColor.end()){
         set <string< x = i->second;
         set <string< :: iterator z = x.begin();
         while(z != x.end()){
            z++;
         }
         cout << endl;
         i++;
      }
   }
   vector<string< generateSentences(vector<vector<string<>& s, string t) {
      int n = s.size();
      for(int i = 0; i < n; i++){
         string x = s[i][0];
         string y = s[i][1];
         if(parent.find(x) == parent.end())parent[x] = x;
            if(parent.find(y) == parent.end())parent[y] = y;
               unionNode(x,y);
      }
      int c = 1;
      for(int i = 0; i < n; i++){
         string x = s[i][0];
         string z = s[i][1];
         string y = find(x);
         if(color.find(y) == color.end()){
            color[y] = c;
            c++;
         }
         color[x] = color[y];
         color[z] = color[y];
         if(groupByColor.find(color[x]) == groupByColor.end()){
            set <string< ss;
            ss.insert(x);
            ss.insert(y);
            groupByColor[color[x]] = ss;
         }
         else{
            groupByColor[color[x]].insert(x);
            groupByColor[color[x]].insert(z);
         }
      }
      vector <string< strings = getString(t);
      dfs(strings, 0);
      sort(ans.begin(), ans.end());
      return ans;
   }
};
main(){
   Solution ob;
   vector<vector<string<> v = {{"happy","joy"},{"sad","sorrow"},{"joy","cheerful"}};
   print_vector(ob.generateSentences(v, "I am happy today but was sad yesterday"));
}

Input

[["happy","joy"],["sad","sorrow"],["joy","cheerful"]] "I am happy today but was sad yesterday"

Output

[I am cheerful today but was sad yesterday, I am cheerful today but was sorrow yesterday, I am happy today but was sad yesterday, I am happy today but was sorrow yesterday, I am joy today but was sad yesterday, I am joy today but was sorrow yesterday, ]

Advertisements