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 subsequences in first string which are anagrams of the second string
Given two strings str1 and str2 of length n1 and n2 respectively. The problem is to count all the subsequences of str1 which are anagrams of str2. Examples: Input : str1 = "abacd", str2 = "abc" Output : 2 Index of characters in the 2 subsequences are: {0, 1, 3} = {a, b, c} = abc and {1, 2, 3} = {b,
13 min read
Increase the count of given subsequences by optimizing the Array
Given an array X[] of length N. Which contains the alternate frequency of 0s and 1s in Binary String starting from 0. Then the task is to maximize the count of the "01" subsequence where you can choose two different elements of X[], let's say Xi and Xj such that abs (i - j) = 2, and then swap Xi and
11 min read
Construct a string that has exactly K subsequences from given string
Given a string str and an integer K, the task is to find a string S such that it has exactly K subsequences of given string str. Examples: Input: str = "gfg", K = 10 Output: gggggffg Explanation: There are 10 possible subsequence of the given string "gggggffg". They are: 1. gggggffg 2. gggggffg 3. g
7 min read
Count strings that end with the given pattern
Given a pattern pat and a string array sArr[], the task is to count the number of strings from the array that ends with the given pattern. Examples: Input: pat = "ks", sArr[] = {"geeks", "geeksforgeeks", "games", "unit"} Output: 2 Only string "geeks" and "geeksforgeeks" end with the pattern "ks". In
7 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