 Open in App
Not now

# Count the strings that are subsequence of the given string

• Difficulty Level : Expert
• Last Updated : 21 Feb, 2023

Given a string S and an array arr[] of words, the task is to return the number of words from the array which is a subsequence of S.

Examples:

Input: S = “programming”, arr[] = {“prom”, “amin”, “proj”}
Output: 2
Explanation: “prom” and “amin” are subsequence of S while “proj” is not)

Input: S = “geeksforgeeks”, arr[] = {“gfg”, “geek”, “geekofgeeks”, “for”}
Output: 3
Explanation:” gfg”, “geek” and “for” are subsequences of S while “geekofgeeks” is not.

Naive Approach:  The basic way to solve the problem is as follows:

The idea is to check all strings in the words array arr[] which are subsequences of S by recursion.

Below is the implementation of the above approach:

## C++

 `// C++ code for the above approach:`   `#include ` `using` `namespace` `std;`   `bool` `isSubsequence(string& str1, ``int` `m, string& str2, ``int` `n)` `{` `    ``if` `(m == 0)` `        ``return` `true``;` `    ``if` `(n == 0)` `        ``return` `false``;`   `    ``// If last characters of two strings` `    ``// are matching` `    ``if` `(str1[m - 1] == str2[n - 1])` `        ``return` `isSubsequence(str1, m - 1, str2, n - 1);`   `    ``// If last characters are not matching` `    ``return` `isSubsequence(str1, m, str2, n - 1);` `}`   `// Function to count number of words that` `// are subsequence of given string S` `int` `countSubsequenceWords(string s, vector& arr)` `{`   `    ``int` `n = arr.size();` `    ``int` `m = s.length();` `    ``int` `res = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``if` `(isSubsequence(arr[i], arr[i].size(), s, m)) {` `            ``res++;` `        ``}` `    ``}` `    ``return` `res;` `}`   `// Driver Code` `int` `main()` `{` `    ``string S = ``"geeksforgeeks"``;` `    ``vector arr` `        ``= { ``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"` `};`   `    ``// Function call` `    ``cout << countSubsequenceWords(S, arr) << ``"\n"``;` `    ``return` `0;` `}`

## Java

 `// Java code for the above approach:` `import` `java.util.*;`   `class` `GFG {`   `  ``static` `boolean` `isSubsequence(String str1, ``int` `m, String str2, ``int` `n)` `  ``{` `    ``if` `(m == ``0``)` `      ``return` `true``;` `    ``if` `(n == ``0``)` `      ``return` `false``;`   `    ``// If last characters of two strings` `    ``// are matching` `    ``if` `(str1.charAt(m-``1``) == str2.charAt(n - ``1``))` `      ``return` `isSubsequence(str1, m - ``1``, str2, n - ``1``);`   `    ``// If last characters are not matching` `    ``return` `isSubsequence(str1, m, str2, n - ``1``);` `  ``}`   `  ``// Function to count number of words that` `  ``// are subsequence of given string S` `  ``static` `int` `countSubsequenceWords(String s, List arr)` `  ``{`   `    ``int` `n = arr.size();` `    ``int` `m = s.length();` `    ``int` `res = ``0``;` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``if` `(isSubsequence(arr.get(i), arr.get(i).length(), s, m)) {` `        ``res++;` `      ``}` `    ``}` `    ``return` `res;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``String S = ``"geeksforgeeks"``;` `    ``List arr` `      ``= ``new` `ArrayList();` `    ``arr.add(``"geek"``);` `    ``arr.add(``"for"``);` `    ``arr.add(``"geekofgeeks"``);` `    ``arr.add(``"gfg"``);`   `    ``// Function call` `    ``System.out.print(countSubsequenceWords(S, arr));` `  ``}` `}`   `// This code is contributed by agrawalpoojaa976.`

## Python3

 `# Python3 code for the above approach`   `# Function to Compare if word is subsequence of string` `def` `issubsequence(str1: ``str``, m: ``int``, str2: ``str``, n: ``int``) ``-``> ``bool``:` `   `  `    ``if` `m ``=``=` `0``:` `        ``return` `True` `    ``if` `n ``=``=` `0``:` `        ``return` `False` `      `  `    ``# If last characters of two strings are matching` `    ``if` `str1[m ``-` `1``] ``=``=` `str2[n ``-` `1``]:` `        ``return` `issubsequence(str1, m ``-` `1``, str2, n ``-` `1``)` `      `  `      ``# If last characters are not matching` `    ``return` `issubsequence(str1, m, str2, n ``-` `1``)`   `# Function to count number of words ` `# that are subsequence of given string S` `def` `countsubsequencewords(s: ``str``, arr: ``list``) ``-``> ``int``:` `    ``res ``=` `0` `    ``for` `word ``in` `arr:` `        ``if` `issubsequence(word, ``len``(word), s, ``len``(s)):` `            ``res ``+``=` `1` `    ``return` `res`   `# Drive code` `S ``=` `"geeksforgeeks"` `arr ``=` `[``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"``]`   `# Function call` `print``(countsubsequencewords(S, arr))`   `#This code is contributed by nikhilsainiofficial546`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `class` `GFG {`   `  ``static` `bool` `isSubsequence(``string` `str1, ``int` `m, ``string` `str2, ``int` `n)` `  ``{` `    ``if` `(m == 0)` `      ``return` `true``;` `    ``if` `(n == 0)` `      ``return` `false``;`   `    ``// If last characters of two strings` `    ``// are matching` `    ``if` `(str1[m - 1] == str2[n - 1])` `      ``return` `isSubsequence(str1, m - 1, str2, n - 1);`   `    ``// If last characters are not matching` `    ``return` `isSubsequence(str1, m, str2, n - 1);` `  ``}`   `  ``// Function to count number of words that` `  ``// are subsequence of given string S` `  ``static` `int` `countSubsequenceWords(``string` `s, ``string``[] arr)` `  ``{`   `    ``int` `n = arr.Length;` `    ``int` `m = s.Length;` `    ``int` `res = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {` `      ``if` `(isSubsequence(arr[i], arr[i].Length, s, m)) {` `        ``res++;` `      ``}` `    ``}` `    ``return` `res;` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `Main() ` `  ``{` `    ``string` `S = ``"geeksforgeeks"``;` `    ``string``[] arr = { ``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"` `};`   `    ``// Function call` `    ``Console.Write(countSubsequenceWords(S, arr) + ``"\n"``);` `  ``}` `}`   `// This code is contributed by ratiagarwal.`

## Javascript

 `// Javascript code for the above approach:`   `function` `isSubsequence(str1, m, str2, n)` `{` `    ``if` `(m == 0)` `        ``return` `true``;` `    ``if` `(n == 0)` `        ``return` `false``;`   `    ``// If last characters of two strings` `    ``// are matching` `    ``if` `(str1[m - 1] == str2[n - 1])` `        ``return` `isSubsequence(str1, m - 1, str2, n - 1);`   `    ``// If last characters are not matching` `    ``return` `isSubsequence(str1, m, str2, n - 1);` `}`   `// Function to count number of words that` `// are subsequence of given string S` `function` `countSubsequenceWords(s, arr)` `{`   `    ``let n = arr.length;` `    ``let m = s.length;` `    ``let res = 0;` `    ``for` `(let i = 0; i < n; i++) {` `        ``if` `(isSubsequence(arr[i], arr[i].length, s, m)) {` `            ``res++;` `        ``}` `    ``}` `    ``return` `res;` `}`   `// Driver Code` `let S = ``"geeksforgeeks"``;` `let arr = [ ``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"` `];`   `// Function call` `console.log(countSubsequenceWords(S, arr));`   `// This code is contributed by poojaagarwal2.`

Output

`3`

Time Complexity: O(m*n)
Auxiliary Space: O(m) for recursion stack space

Efficient Approach: The above approach can be optimized based on the following idea:

• Map the index of characters of the given string to the respective characters array.
• Initialize the ans with the size of arr.
• Iterate over all the words in arr one by one.
• Iterate over each character.
• Find strictly greater index than prevIndex in dict.
• If the strictly greater element is not found, it means the current word is not a subsequence of the given string, so decrease res by 1.
• Else update prevIndex.
• After iterating over all the words, return ans.

Below is the implementation of the above approach:

## C++

 `// C++ code for the above approach:`   `#include ` `using` `namespace` `std;`   `// Function to count number of words that` `// are subsequence of given string S` `int` `countSubsequenceWords(string s, vector& arr)` `{` `    ``unordered_map<``char``, vector<``int``> > dict;`   `    ``// Mapping index of characters of given` `    ``// string to respective characters` `    ``for` `(``int` `i = 0; i < s.length(); i++) {` `        ``dict[s[i]].push_back(i);` `    ``}`   `    ``// Initializing res with size of arr` `    ``int` `res = arr.size();`   `    ``for` `(``auto` `word : arr) {`   `        ``// Index where last character` `        ``// is found` `        ``int` `prevIndex = -1;` `        ``for` `(``int` `j = 0; j < word.size(); j++) {`   `            ``// Searching for strictly` `            ``// greater element than prev` `            ``// using binary search` `            ``auto` `x = upper_bound(dict[word[j]].begin(),` `                                 ``dict[word[j]].end(),` `                                 ``prevIndex);`   `            ``// If strictly greater index` `            ``// not found, the word cannot` `            ``// be subsequence of string s` `            ``if` `(x == dict[word[j]].end()) {` `                ``res--;` `                ``break``;` `            ``}`   `            ``// Else, update the prevIndex` `            ``else` `{` `                ``prevIndex = *x;` `            ``}` `        ``}` `    ``}` `    ``return` `res;` `}`   `// Driver Code` `int` `main()` `{` `    ``string S = ``"geeksforgeeks"``;` `    ``vector arr` `        ``= { ``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"` `};`   `    ``// Function call` `    ``cout << countSubsequenceWords(S, arr) << ``"\n"``;`   `    ``return` `0;` `}`

## Java

 `import` `java.util.*;`   `class` `Main` `{`   `  ``// Function to count number of words that` `  ``// are subsequence of given string S` `  ``static` `int` `countSubsequenceWords(String s, List arr) {` `    ``Map > dict = ``new` `HashMap<>();`   `    ``// Mapping index of characters of given` `    ``// string to respective characters` `    ``for` `(``int` `i = ``0``; i < s.length(); i++) {` `      ``char` `c = s.charAt(i);` `      ``List list = dict.getOrDefault(c, ``new` `ArrayList<>());` `      ``list.add(i);` `      ``dict.put(c, list);` `    ``}`   `    ``// Initializing res with size of arr` `    ``int` `res = arr.size();`   `    ``for` `(String word : arr)` `    ``{`   `      ``// Index where last character` `      ``// is found` `      ``int` `prevIndex = -``1``;` `      ``for` `(``int` `j = ``0``; j < word.length(); j++) ` `      ``{`   `        ``// Searching for strictly` `        ``// greater element than prev` `        ``// using binary search` `        ``List indices = dict.get(word.charAt(j));` `        ``int` `x = binarySearch(indices, prevIndex);`   `        ``// If strictly greater index` `        ``// not found, the word cannot` `        ``// be subsequence of string s` `        ``if` `(x == -``1``) {` `          ``res--;` `          ``break``;` `        ``}`   `        ``// Else, update the prevIndex` `        ``else` `{` `          ``prevIndex = indices.get(x);` `        ``}` `      ``}` `    ``}` `    ``return` `res;` `  ``}`   `  ``static` `int` `binarySearch(List indices, ``int` `target) {` `    ``int` `l = ``0``, r = indices.size() - ``1``;` `    ``while` `(l <= r) {` `      ``int` `mid = l + (r - l) / ``2``;` `      ``if` `(indices.get(mid) <= target) {` `        ``l = mid + ``1``;` `      ``} ``else` `{` `        ``r = mid - ``1``;` `      ``}` `    ``}` `    ``return` `l < indices.size() ? l : -``1``;` `  ``}`   `  ``public` `static` `void` `main(String[] args) {` `    ``String S = ``"geeksforgeeks"``;` `    ``List arr = Arrays.asList(``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"``);`   `    ``// Function call` `    ``System.out.println(countSubsequenceWords(S, arr));` `  ``}` `}`   `// This code is contributed by lokeshpotta20.`

## Python3

 `import` `collections`   `# Function to count number of words that` `# are subsequence of given string S` `def` `countSubsequenceWords(s, arr):` `    ``dict` `=` `collections.defaultdict(``list``)`   `    ``# Mapping index of characters of given` `    ``# string to respective characters` `    ``for` `i ``in` `range``(``len``(s)):` `        ``dict``[s[i]].append(i)`   `    ``# Initializing res with size of arr` `    ``res ``=` `len``(arr)`   `    ``for` `word ``in` `arr:` `        ``# Index where last character` `        ``# is found` `        ``prevIndex ``=` `-``1` `        ``for` `j ``in` `range``(``len``(word)):` `            ``# Searching for strictly` `            ``# greater element than prev` `            ``# using binary search` `            ``x ``=` `None` `            ``for` `i ``in` `range``(``len``(``dict``[word[j]])):` `                ``if` `dict``[word[j]][i] > prevIndex:` `                    ``x ``=` `dict``[word[j]][i]` `                    ``break` `            `  `            ``# If strictly greater index` `            ``# not found, the word cannot` `            ``# be subsequence of string s` `            ``if` `x ``is` `None``:` `                ``res ``-``=` `1` `                ``break` `            ``else``:` `                ``prevIndex ``=` `x` `    ``return` `res`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `    ``S ``=` `"geeksforgeeks"` `    ``arr ``=` `[``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"``]`   `    ``# Function call` `    ``print``(countSubsequenceWords(S, arr))`

## C#

 `// C# code for the above approach:` `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG ` `{` `  `  `  ``// Function to count number of words that` `  ``// are subsequence of given string S` `  ``static` `int` `CountSubsequenceWords(``string` `s,` `                                   ``List<``string``> arr)` `  ``{` `    ``Dictionary<``char``, List<``int``> > dict` `      ``= ``new` `Dictionary<``char``, List<``int``> >();`   `    ``// Mapping index of characters of given` `    ``// string to respective characters` `    ``for` `(``int` `i = 0; i < s.Length; i++) {` `      ``char` `c = s[i];` `      ``if` `(!dict.ContainsKey(c))` `        ``dict = ``new` `List<``int``>();` `      ``dict.Add(i);` `    ``}`   `    ``// Initializing res with size of arr` `    ``int` `res = arr.Count;`   `    ``foreach``(``string` `word ``in` `arr)` `    ``{` `      ``// Index where last character` `      ``// is found` `      ``int` `prevIndex = -1;` `      ``for` `(``int` `j = 0; j < word.Length; j++) {`   `        ``// Searching for strictly` `        ``// greater element than prev` `        ``// using binary search` `        ``List<``int``> indices = dict[word[j]];` `        ``int` `x = BinarySearch(indices, prevIndex);`   `        ``// If strictly greater index` `        ``// not found, the word cannot` `        ``// be subsequence of string s` `        ``if` `(x == -1) {` `          ``res--;` `          ``break``;` `        ``}`   `        ``// Else, update the prevIndex` `        ``else` `{` `          ``prevIndex = indices[x];` `        ``}` `      ``}` `    ``}` `    ``return` `res;` `  ``}`   `  ``static` `int` `BinarySearch(List<``int``> indices, ``int` `target)` `  ``{` `    ``int` `l = 0, r = indices.Count - 1;` `    ``while` `(l <= r) {` `      ``int` `mid = l + (r - l) / 2;` `      ``if` `(indices[mid] <= target) {` `        ``l = mid + 1;` `      ``}` `      ``else` `{` `        ``r = mid - 1;` `      ``}` `    ``}` `    ``return` `l < indices.Count ? l : -1;` `  ``}`   `  ``static` `public` `void` `Main(``string``[] args)` `  ``{` `    ``string` `S = ``"geeksforgeeks"``;` `    ``List<``string``> arr` `      ``= ``new` `List<``string``>{ ``"geek"``, ``"for"``,` `                         ``"geekofgeeks"``, ``"gfg"` `};`   `    ``// Function call` `    ``Console.WriteLine(CountSubsequenceWords(S, arr));` `  ``}` `}`   `// This code is contributed by Prasad Kandekar(prasad264)`

## Javascript

 `// JavaScript code for the above approach:`   `// Function to count number of words that are subsequence of given string S` `function` `countSubsequenceWords(s, arr) {` `    ``let dict = {};`   `    ``// Mapping index of characters of given string to respective characters` `    ``for` `(let i = 0; i < s.length; i++) {` `        ``let c = s[i];` `        ``let list = dict || [];` `        ``list.push(i);` `        ``dict = list;` `    ``}`   `    ``// Initializing res with size of arr` `    ``let res = arr.length;`   `    ``for` `(let word of arr) {`   `        ``// Index where last character is found` `        ``let prevIndex = -1;` `        ``for` `(let j = 0; j < word.length; j++) {`   `            ``// Searching for strictly greater element than prev` `            ``// using binary search` `            ``let indices = dict[word[j]] || [];` `            ``let x = binarySearch(indices, prevIndex);`   `            ``// If strictly greater index not found, the word cannot` `            ``// be subsequence of string s` `            ``if` `(x === -1) {` `                ``res--;` `                ``break``;` `            ``}`   `            ``// Else, update the prevIndex` `            ``else` `{` `                ``prevIndex = indices[x];` `            ``}` `        ``}` `    ``}` `    ``return` `res;` `}`   `function` `binarySearch(indices, target) {` `    ``let l = 0, r = indices.length - 1;` `    ``while` `(l <= r) {` `        ``let mid = l + Math.floor((r - l) / 2);` `        ``if` `(indices[mid] <= target) {` `            ``l = mid + 1;` `        ``} ``else` `{` `            ``r = mid - 1;` `        ``}` `    ``}` `    ``return` `l < indices.length ? l : -1;` `}`   `let S = ``"geeksforgeeks"``;` `let arr = [``"geek"``, ``"for"``, ``"geekofgeeks"``, ``"gfg"``];`   `// Function call` `console.log(countSubsequenceWords(S, arr));`   `// This code is contributed by lokesh.`

Output

`3`

Time Complexity: O( m * s * log(n) ), where m is the length of the given string, s is the max length of the word of arr and n is the length of arr
Auxiliary Space: O(n)

My Personal Notes arrow_drop_up
Related Articles