Check if substring S1 appear after any occurrence of substring S2 in given sentence


In this problem, we need th check whether the substring S1 appears after any occurrence of the substring S2 in the given string S. We can compare the starting index of S1 and S2 in the string S to solve the problem.

Problem statement – We have given three substrings named S, S1, and S2. The string S always contains S1 as a substring. We need to check whether the substring S1 appears after any occurrence of the substring S2 in the given string S.

Sample examples

Input – S = "abxtutorialspointwelcomepoint", S1 = "welcome", S2 = "point";

Output – Yes

Explanation – In the string S, the ‘point’ substring occurs 2 times. One is before ‘welcome’, and another is after that. So, We can say that string S1 appears after any occurrence of string S2

Input–   S = "abcdefgh", S1 = "abcd", S2 = "gh";

Output – No

ExplanationS1 is at the start of the string S. So, S1 doesn’t appear after substring S2.

Input – S = "abce", S1 = "bc", S2 = "xy";

Output – No

Explanation– As string S2 is not present in the string S, it prints No.

Approach 1

In this approach, we will find all starting indexes of the S2 substring and store them in the set. After that, we will get the starting index of the S1. We will compare each starting index of S2 with starting index of S1, and if we find any value from the set which is less than starting index of S2, we can say substring S1 appears after any occurrence of substring S2.

Algorithm

  • Define the set to store the starting indexes of substring S2.

  • Use the find() method to find the first starting index of the S2 substring.

  • Use the while loop to get all starting indexes of substring S2 and use the insert() method to store them in the set.

  • Traverse the set values. Return true if any value is less than the starting index of substring S1 in the given string S.

  • At last, return false.

Example

#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;
bool isS1AfterS2(string& S, string& S1, string& S2) {
   // set to store indices of S2 in S
   unordered_set<int> indices;
   // Find all occurrences of S2 in S, and store them in set
   size_t found = S.find(S2);
   while (found != string::npos) {
      indices.insert(found);
      found = S.find(S2, found + 1);
   }
   // Compare starting indices of S1 with S2
   for (const int& index : indices) {
      if (index < S.find(S1)) {
          return true;  // S2 appears before S1
      }
   }
   return false;  // S1 appears before or at the same position as S2
}
int main(){
   string S = "abxtutorialspointwelcomepoint";
   string S1 = "welcome", S2 = "point";
   if(isS1AfterS2(S, S1, S2)) {
          cout << "Yes, string S1 appears after string S2.";
   } else { 
      cout << "No, string S1 does not appear after string S2.";
   }
   return 0;
}

Output

Yes, string S1 appears after string S2.

Time complexity – O(N*K) as we need to find starting indexes of string S2.

Space complexity – O(N) as we store starting indexes of string S2.

Approach 2

In this approach, we will traverse the string. If we find the occurrence of S2 before the occurrence of S1, we return true as string S always contains the string S1.

Algorithm

  • Define the len, n1, and n2 variables to store the length of the variable.

  • Start traversing the string.

  • Define the ‘temp string and initialize it with the substring of length n2 starting from the ith index.

  • If temp == S2, return true.

  • Take a substring of length n1 starting from the ith index. If temp == s1, return false.

  • Return true at the end.

Example

#include <bits/stdc++.h>
using namespace std;
bool isS1AfterS2(string &S, string &S1, string &S2){
   // store the length of the strings
   int n1 = S1.size(), n2 = S2.size();
   // Traverse the string S from left to right
   for (int i = 0; i <= S.size() - n2; i++){
      // temporary string to store substring
      string temp;
      // get the substring
      temp = S.substr(i, n2);
      // if we find the string S2, return true as s1 always present in s.
      if (temp == S2){
          return true;
      }
      temp = S.substr(i, n1);
      // If we find s1 before s2, return false
      if (temp == S1){
          return false;
      }
   }
   return true;
}
int main(){
   string S = "abxtutorialspointwelcome";
   string S1 = "welcome", S2 = "point";
   if(isS1AfterS2(S, S1, S2)) {
      cout << "Yes, string S1 appears after string S2.";
   } else { 
      cout << "No, string S1 does not appear after string S2.";
   }
   return 0;
}

Output

Yes, string S1 appears after string S2.

Time complexity – O(N*min(n1, n2)) as we find substring of length n1 and n2.

Space complexity – O(min(n1, n2) as we store the substring.

In the first approach, we used the set to store the starting indexes of S2, which requires more space than the code of the second approach. The second approach’s code is more readable than the first. Also, programmers can try to solve the problem of checking whether substring S2 appears after any occurrence of S1.

Updated on: 17-Aug-2023

164 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements