Sentence Similarity II in C++


Suppose we have Given two arrays words1, words2 these are considered as sentences, and a list of similar word pairs, we have to check whether two sentences are similar or not. So if the input is like words1 = ["great", "acting", "skills"] and words2 = ["fine", "drama", "talent"] these two are similar, if the similar word pairs are like = [["great", "good"], ["fine", "good"], ["acting","drama"], ["skills","talent"]].

The similarity relation is transitive. For example, if "great" and "good" are similar, and "fine" and "good" are similar, then "great" and "fine" are also similar. And the similarity is also symmetric. So, "great" and "fine" being similar is the same as "fine" and "great" is similar. A word is always similar to itself. Finally, sentences can only be similar if they have the same number of words.

To solve this, we will follow these steps −

  • Define one map parent, another map idx

  • Define a function getParent(), this will take x,

  • if x is not in parent, then −

    • return x

  • parent[x] := getParent(parent[x])

  • return parent[x]

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

  • parentA := getParent(idx[a])

  • parentB := getParent(idx[b])

  • if parentA is same as parentB, then −

    • return

  • parent[parentA] := parentB

  • From the main method do the following −

  • if size of words1 is not equal to size of words2, then −

    • return false

  • n := size of words1

  • counter := 1

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

    • if words1[i] is not in idx, then −

      • idx[words1[i]] := counter, then increase counter by 1

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

    • if words2[i] is not in idx, then −

      • idx[words2[i]] := counter, then increase counter by 1

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

    • u := pairs[i,0]

    • v := pairs[i,1]

    • if u not in idx, then −

      • idx[u] := counter, then increase counter by 1

    • if v not in idx, then −

      • idx[v] := counter, then increase counter by 1

    • unionn(u, v)

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

    • u := words1[i]

    • v := words2[i]

    • if u is same as v, then −

      • Ignore following part, skip to the next iteration

    • if getParent(idx[u]) is not equal to getParent(idx[v]), then −

      • return false

  • return true

Example 

Let us see the following implementation to get better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   unordered_map<int, int> parent;
   unordered_map<string, int> idx;
   int getParent(int x){
      if (!parent.count(x))
         return x;
      return parent[x] = getParent(parent[x]);
   }
   void unionn(string a, string b){
      int parentA = getParent(idx[a]);
      int parentB = getParent(idx[b]);
      if (parentA == parentB)
         return;
      parent[parentA] = parentB;
   }
   bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2, vector<vector<string> >& pairs){
      if (words1.size() != words2.size())
         return false;
      int n = words1.size();
      int counter = 1;
      for (int i = 0; i < n; i++) {
         if (!idx.count(words1[i])) {
            idx[words1[i]] = counter++;
         }
      }
      for (int i = 0; i < n; i++) {
         if (!idx.count(words2[i])) {
            idx[words2[i]] = counter++;
         }
      }
      for (int i = 0; i < pairs.size(); i++) {
         string u = pairs[i][0];
         string v = pairs[i][1];
         if (!idx.count(u)) {
            idx[u] = counter++;
         }
         if (!idx.count(v)) {
            idx[v] = counter++;
         }
         unionn(u, v);
      }
      for (int i = 0; i < n; i++) {
         string u = words1[i];
         string v = words2[i];
         if (u == v)
            continue;
         if (getParent(idx[u]) != getParent(idx[v]))
         return false;
      }
      return true;
   }
};
main(){
   Solution ob;
   vector<string> v = { "great", "acting", "skills" }, v1 = { "fine", "drama", "talent" };
   vector<vector<string> > v2 = { { "great", "good" }, { "fine", "good" }, { "drama", "acting" }, { "skills", "talent" } };
   cout << (ob.areSentencesSimilarTwo(v, v1, v2));
}

Input

{"great","acting","skills"}, {"fine","drama","talent"},
{{"great","good"},{"fine","good"},{"drama","acting"},{"skills","talent"}}

Output

1

Updated on: 17-Nov-2020

239 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements