Count the strings that are subsequence of the given string
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 <bits/stdc++.h>
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<string>& 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<string> 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<String> 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<String> arr
= new ArrayList<String>();
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.
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 <bits/stdc++.h>
using namespace std;
// Function to count number of words that
// are subsequence of given string S
int countSubsequenceWords(string s, vector<string>& 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<string> 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<String> arr) {
Map<Character, List<Integer> > 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<Integer> 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<Integer> 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<Integer> 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<String> 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[c] = new List<int>();
dict[c].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[c] || [];
list.push(i);
dict[c] = 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.
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)
Similar Reads
Count of Subsequences of given string X in between strings Y and Z Given three strings, 'X', 'Y' and 'Z', the task is to count the number of subsequences of 'X' which is lexicographically greater than or equal to 'Y' and lexicographically lesser than or equal to 'Z'. Examples: Input: X = "abc", Y = "a", Z = "bc"Output: 6Explanation: The subsequences of X which are
15+ min read
Count subsequence of length three in a given string Given a string of length n and a subsequence of length 3. Find the total number of occurrences of the subsequence in this string. Examples : Input : string = "GFGFGYSYIOIWIN", subsequence = "GFG" Output : 4 Explanation : There are 4 such subsequences as shown: GFGFGYSYIOIWIN GFGFGYSYIOIWIN GFGFGYSYI
15 min read
Count binary Strings that does not contain given String as Subsequence Given a number N and string S, count the number of ways to create a binary string (containing only '0' and '1') of size N such that it does not contain S as a subsequence. Examples: Input: N = 3, S = "10".Output: 4Explanation: There are 8 strings possible to fill 3 positions with 0's or 1's. {"000",
15+ min read
Count of 'GFG' Subsequences in the given string Given a string of length n of capital letters. The task is to find the count of 'GFG' subsequence in the given string. Examples: Input : str[] = "GFGFG" Output : 4 GFGFG, GFGFG, GFGFG, GFGFG Input : str[] = "ABCFGFPG" Output : 1 To find the number of "GFG" subsequences in the given string, observe f
5 min read
Count of unique Subsequences of given String with lengths in range [0, N] Given a string S of length N, the task is to find the number of unique subsequences of the string for each length from 0 to N. Note: The uppercase letters and lowercase letters are considered different and the result may be large so print it modulo 1000000007. Examples: Input: S = "ababd"Output: Num
14 min read
Count of substrings that start and end with 1 in given Binary String Given a binary string, count the number of substrings that start and end with 1. Examples: Input: "00100101"Output: 3Explanation: three substrings are "1001", "100101" and "101" Input: "1001"Output: 1Explanation: one substring "1001" Recommended PracticeCount SubstringsTry It!Count of substrings tha
12 min read
Count All Palindromic Subsequence in a given String Given a string s of length n, the task is to count number of palindromic subsequence (need not necessarily be distinct) present in the string s.Example: Input: s = "abcd"Output: 4Explanation: Palindromic subsequence are : "a" ,"b", "c" ,"d"Input: s = "aab"Output: 4Explanation: palindromic subsequenc
15+ min read
Count of sub-strings that do not consist of the given character Given a string str and a character c. The task is to find the number of sub-strings that do not consist of the character c. Examples: Input: str = "baa", c = 'b' Output: 3 The sub-strings are "a", "a" and "aa" Input: str = "ababaa", C = 'b' Output: 5 Approach: Initially take a counter that counts th
12 min read
Subsequences of given string consisting of non-repeating characters Given a string str of length N, the task is to print all possible distinct subsequences of the string str which consists of non-repeating characters only. Examples: Input: str = "abac" Output: a ab abc ac b ba bac bc c Explanation: All possible distinct subsequences of the strings are { a, aa, aac,
7 min read