Queries to check if string B exists as substring in string A
Last Updated :
17 Apr, 2023
Given two strings A, B and some queries consisting of an integer i, the task is to check whether the sub-string of A starting from index i and ending at index i + length(B) - 1 equals B or not. If equal then print Yes else print No. Note that i + length(B) will always be smaller than length(A).
Examples:
Input: A = "abababa", B = "aba", q[] = {0, 1, 2, 3}
Output:
Yes
No
Yes
No
a[0-2] = "aba" = b (both are equal)
a[1-3] = "bab" != b
a[2-4] = "aba" = b
a[3-5] = "bab" !=b
Input: A = "GeeksForGeeks", B = "Geeks", q[] = {0, 5, 8}
Output:
Yes
No
Yes
A simple approach will be to compare the strings character by character for every query which will take O(length(B)) time to answer each query.
Efficient approach: We will optimize the query processing using rolling hash algorithm.
First, we will find hash value of string B. Then, using rolling hash technique, we will do the pre-processing of string A.
Let's suppose we created an array hash_A. Then ith element of this array will store.
((a[0] - 97) + (a[1] - 97) * d + (a[2] - 97) * d2 + ..... + (a[i] - 97) * di) % mod
where d is the multiplier in rolling-hash.
We will use this to find hash of the sub-string of A.
Hash of sub-string of A starting from i can be found as (hash_a[i + len_b - 1] - hash_a[i - 1]) / di or more specifically
((hash_a[i + len_b - 1] - hash_a[i - 1] + 2 * mod) * mi(di)) % mod
Thus, using this we can answer each query in O(1).
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
#define mod 3803
#define d 26
using namespace std;
int hash_b;
int* hash_a;
int* mul;
// Function to return the modular inverse
// using Fermat's little theorem
int mi(int x)
{
int p = mod - 2;
int s = 1;
while (p != 1) {
if (p % 2 == 1)
s = (s * x) % mod;
x = (x * x) % mod;
p /= 2;
}
return (s * x) % mod;
}
// Function to generate hash
void genHash(string& a, string& b)
{
// To store prefix-sum
// of rolling hash
hash_a = new int[a.size()];
// Multiplier for different values of i
mul = new int[a.size()];
// Generating hash value for string b
for (int i = b.size() - 1; i >= 0; i--)
hash_b = (hash_b * d + (b[i] - 97)) % mod;
// Generating prefix-sum of hash of a
mul[0] = 1;
hash_a[0] = (a[0] - 97) % mod;
for (int i = 1; i < a.size(); i++) {
mul[i] = (mul[i - 1] * d) % mod;
hash_a[i]
= (hash_a[i - 1] + mul[i] * (a[i] - 97)) % mod;
}
}
// Function that returns true if the
// required sub-string in a is equal to b
bool checkEqual(int i, int len_a, int len_b)
{
// To store hash of required
// sub-string of A
int x;
// If i = 0 then
// requires hash value
if (i == 0)
x = hash_a[len_b - 1];
// Required hash if i != 0
else {
x = (hash_a[i + len_b - 1] - hash_a[i - 1]
+ 2 * mod)
% mod;
x = (x * mi(mul[i])) % mod;
}
// Comparing hash with hash of B
if (x == hash_b)
return true;
return false;
}
// Driver code
int main()
{
string a = "abababababa";
string b = "aba";
// Generating hash
genHash(a, b);
// Queries
int queries[] = { 0, 1, 2, 3 };
int q = sizeof(queries) / sizeof(queries[0]);
// Perform queries
for (int i = 0; i < q; i++) {
if (checkEqual(queries[i], a.size(), b.size()))
cout << "Yes\n";
else
cout << "No\n";
}
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG {
static int mod = 3803;
static int d = 26;
static int hash_b;
static int[] hash_a;
static int[] mul;
// Function to return the modular inverse
// using Fermat's little theorem
static int mi(int x)
{
int p = mod - 2;
int s = 1;
while (p != 1) {
if (p % 2 == 1) {
s = (s * x) % mod;
}
x = (x * x) % mod;
p /= 2;
}
return (s * x) % mod;
}
// Function to generate hash
static void genHash(char[] a, char[] b)
{
// To store prefix-sum
// of rolling hash
hash_a = new int[a.length];
// Multiplier for different values of i
mul = new int[a.length];
// Generating hash value for string b
for (int i = b.length - 1; i >= 0; i--) {
hash_b = (hash_b * d + (b[i] - 97)) % mod;
}
// Generating prefix-sum of hash of a
mul[0] = 1;
hash_a[0] = (a[0] - 97) % mod;
for (int i = 1; i < a.length; i++) {
mul[i] = (mul[i - 1] * d) % mod;
hash_a[i]
= (hash_a[i - 1] + mul[i] * (a[i] - 97))
% mod;
}
}
// Function that returns true if the
// required sub-string in a is equal to b
static boolean checkEqual(int i, int len_a, int len_b)
{
// To store hash of required
// sub-string of A
int x;
// If i = 0 then
// requires hash value
if (i == 0) {
x = hash_a[len_b - 1];
}
// Required hash if i != 0
else {
x = (hash_a[i + len_b - 1] - hash_a[i - 1]
+ 2 * mod)
% mod;
x = (x * mi(mul[i])) % mod;
}
// Comparing hash with hash of B
if (x == hash_b) {
return true;
}
return false;
}
// Driver code
public static void main(String[] args)
{
String a = "abababababa";
String b = "aba";
// Generating hash
genHash(a.toCharArray(), b.toCharArray());
// Queries
int queries[] = { 0, 1, 2, 3 };
int q = queries.length;
// Perform queries
for (int i = 0; i < q; i++) {
if (checkEqual(queries[i], a.length(),
b.length())) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
}
}
/* This code is contributed by PrinciRaj1992 */
Python3
# Python3 implementation of the approach
mod = 3803
d = 26
hash_b = 0
hash_a = []
mul = []
# Function to return the modular inverse
# using Fermat's little theorem
def mi(x):
global mod
p = mod - 2
s = 1
while p != 1:
if p % 2 == 1:
s = (s * x) % mod
x = (x * x) % mod
p //= 2
return (s * x) % mod
# Function to generate hash
def genHash(a, b):
global hash_b, hash_a, mul, d, mod
# To store prefix-sum
# of rolling hash
hash_a = [0] * len(a)
# Multiplier for different values of i
mul = [0] * len(a)
# Generating hash value for string b
for i in range(len(b) - 1, -1, -1):
hash_b = (hash_b * d +
(ord(b[i]) - 97)) % mod
# Generating prefix-sum of hash of a
mul[0] = 1
hash_a[0] = (ord(a[0]) - 97) % mod
for i in range(1, len(a)):
mul[i] = (mul[i - 1] * d) % mod
hash_a[i] = (hash_a[i - 1] + mul[i] *
(ord(a[i]) - 97)) % mod
# Function that returns true if the
# required sub-string in a is equal to b
def checkEqual(i, len_a, len_b):
global hash_b, hash_a, mul, d, mod
# To store hash of required
# sub-string of A
x = -1
# If i = 0 then
# requires hash value
if i == 0:
x = hash_a[len_b - 1]
# Required hash if i != 0
else:
x = (hash_a[i + len_b - 1] -
hash_a[i - 1] + 2 * mod) % mod
x = (x * mi(mul[i])) % mod
# Comparing hash with hash of B
if x == hash_b:
return True
return False
# Driver Code
if __name__ == "__main__":
a = "abababababa"
b = "aba"
# Generating hash
genHash(a, b)
# Queries
queries = [0, 1, 2, 3]
q = len(queries)
# Perform queries
for i in range(q):
if checkEqual(queries[i], len(a), len(b)):
print("Yes")
else:
print("No")
# This code is contributed by
# sanjeev2552
C#
// C# implementation of the approach
using System;
class GFG {
static int mod = 3803;
static int d = 26;
static int hash_b;
static int[] hash_a;
static int[] mul;
// Function to return the modular inverse
// using Fermat's little theorem
static int mi(int x)
{
int p = mod - 2;
int s = 1;
while (p != 1) {
if (p % 2 == 1) {
s = (s * x) % mod;
}
x = (x * x) % mod;
p /= 2;
}
return (s * x) % mod;
}
// Function to generate hash
static void genHash(char[] a, char[] b)
{
// To store prefix-sum
// of rolling hash
hash_a = new int[a.Length];
// Multiplier for different values of i
mul = new int[a.Length];
// Generating hash value for string b
for (int i = b.Length - 1; i >= 0; i--) {
hash_b = (hash_b * d + (b[i] - 97)) % mod;
}
// Generating prefix-sum of hash of a
mul[0] = 1;
hash_a[0] = (a[0] - 97) % mod;
for (int i = 1; i < a.Length; i++) {
mul[i] = (mul[i - 1] * d) % mod;
hash_a[i]
= (hash_a[i - 1] + mul[i] * (a[i] - 97))
% mod;
}
}
// Function that returns true if the
// required sub-string in a is equal to b
static Boolean checkEqual(int i, int len_a, int len_b)
{
// To store hash of required
// sub-string of A
int x;
// If i = 0 then
// requires hash value
if (i == 0) {
x = hash_a[len_b - 1];
}
// Required hash if i != 0
else {
x = (hash_a[i + len_b - 1] - hash_a[i - 1]
+ 2 * mod)
% mod;
x = (x * mi(mul[i])) % mod;
}
// Comparing hash with hash of B
if (x == hash_b) {
return true;
}
return false;
}
// Driver code
public static void Main(String[] args)
{
String a = "abababababa";
String b = "aba";
// Generating hash
genHash(a.ToCharArray(), b.ToCharArray());
// Queries
int[] queries = { 0, 1, 2, 3 };
int q = queries.Length;
// Perform queries
for (int i = 0; i < q; i++) {
if (checkEqual(queries[i], a.Length,
b.Length)) {
Console.WriteLine("Yes");
}
else {
Console.WriteLine("No");
}
}
}
}
/* This code contributed by PrinciRaj1992 */
JavaScript
<script>
// Javascript implementation of the approach
var mod = 3803;
var d = 26;
var hash_b = 0;
var hash_a = [];
var mul = [];
// Function to return the modular inverse
// using Fermat's little theorem
function mi(x)
{
var p = mod - 2;
var s = 1;
while (p != 1) {
if (p % 2 == 1)
s = (s * x) % mod;
x = (x * x) % mod;
p = parseInt(p/2);
}
return (s * x) % mod;
}
// Function to generate hash
function genHash(a, b)
{
// To store prefix-sum
// of rolling hash
hash_a = Array(a.length).fill(0);
// Multiplier for different values of i
mul = Array(a.length).fill(0);
// Generating hash value for string b
for (var i = b.length - 1; i >= 0; i--)
hash_b = (hash_b * d + (b[i].charCodeAt(0) - 97)) % mod;
// Generating prefix-sum of hash of a
mul[0] = 1;
hash_a[0] = (a[0].charCodeAt(0) - 97) % mod;
for (var i = 1; i < a.length; i++) {
mul[i] = (mul[i - 1] * d) % mod;
hash_a[i]
= (hash_a[i - 1] + mul[i] * (a[i].charCodeAt(0) - 97)) % mod;
}
}
// Function that returns true if the
// required sub-string in a is equal to b
function checkEqual(i, len_a, len_b)
{
// To store hash of required
// sub-string of A
var x;
// If i = 0 then
// requires hash value
if (i == 0)
x = hash_a[len_b - 1];
// Required hash if i != 0
else {
x = (hash_a[i + len_b - 1] - hash_a[i - 1]
+ 2 * mod)
% mod;
x = (x * mi(mul[i])) % mod;
}
// Comparing hash with hash of B
if (x == hash_b)
return true;
return false;
}
// Driver code
var a = "abababababa";
var b = "aba";
// Generating hash
genHash(a.split(''), b.split(''));
// Queries
var queries = [0, 1, 2, 3];
var q = queries.length
// Perform queries
for (var i = 0; i < q; i++) {
if (checkEqual(queries[i], a.length, b.length))
document.write("Yes<br>");
else
document.write("No<br>");
}
// This code is contributed by rrrtnx.
</script>
Time Complexity: O(N*Q)
Auxiliary Space: O(M*N)
Note: For simplicity, we have used only one hash function. Use double/triple hash to eliminate any chance of collision and more accurate result.
The above question can be solved by using DP also, below is the java code.
C++
#include <bits/stdc++.h>
using namespace std;
void substringCheck(string stra, string strb,
vector<int> query)
{
// Dp Array
int matrix[strb.size()][stra.size()];
// initialize matrix with 1
for (int c = 0; c < stra.size(); c++) {
if (strb[0] == stra[c]) {
matrix[0][c] = 1;
}
}
// for r from 1 to string length
for (int r = 1; r < strb.size(); r++) {
char ch = strb[r];
// for c from 1 b string length
for (int c = 1; c < stra.size(); c++) {
if (ch == stra[c]
&& matrix[r - 1][c - 1] == 1) {
matrix[r][c] = 1;
}
}
}
// For every query
for (auto q : query) {
int matLoc = (q + (strb.size() - 1));
if (matLoc >= stra.size()) {
cout << "false" << endl;
}
else {
// print true
if (matrix[strb.size() - 1][(matLoc)] == 1) {
cout << "true" << endl;
}
else {
// print false
cout << "false" << endl;
}
}
}
}
// Driver Code
int main()
{
string stra = "GeeksForGeeks";
string strb = "Geeks";
vector<int> query = { 0, 5, 8 };
substringCheck(stra, strb, query);
}
// This code is contributed by Samim Hossain Mondal.
Java
import java.io.*;
import java.util.*;
import java.lang.*;
import java.io.*;
public class GFG
{
private static void
substringCheck(String stra, String strb, int[] query)
{
// Dp Array
int[][] matrix
= new int[strb.length()][stra.length()];
// String to character array
char[] charCrr = stra.toCharArray();
char[] charRrr = strb.toCharArray();
// initialize matrix with 1
for (int c = 0; c < stra.length(); c++)
{
if (charRrr[0] == charCrr[c])
{
matrix[0][c] = 1;
}
}
// for r from 1 to string length
for (int r = 1; r < charRrr.length; r++)
{
char ch = charRrr[r];
// for c from 1 b string length
for (int c = 1; c < charCrr.length; c++)
{
if (ch == charCrr[c]
&& matrix[r - 1][c - 1] == 1)
{
matrix[r][c] = 1;
}
}
}
// For every query
for (int q : query)
{
int matLoc = (q + (strb.length() - 1));
if (matLoc >= stra.length()) {
System.out.println(false);
}
else
{
// print true
if (matrix[strb.length() - 1][(matLoc)]
== 1)
{
System.out.println(true);
}
else
{
// print false
System.out.println(false);
}
}
}
}
// Driver Code
public static void main(String[] args)
{
String stra = "GeeksForGeeks";
String strb = "Geeks";
int[] query = { 0,5,8 };
substringCheck(stra, strb, query);
}
} // class
// Code contributed by Swapnil Gupta
Python3
def substringCheck(stra, strb, query):
# Dp Array
# matrix[strb.size()][stra.size()];
n = len(stra)
m = len(strb)
matrix = [[-1] * n for _ in range(m)]
# initialize matrix with 1
for c in range(n):
if strb[0] == stra[c]:
matrix[0][c] = 1
# for r from 1 to string length
for r in range(1, m):
ch = strb[r]
# for c from 1 b string length
for c in range(1, n):
if ch == stra[c] and matrix[r - 1][c - 1] == 1:
matrix[r][c] = 1
# For every query
for q in query:
matLoc = q + (m - 1)
if matLoc >= n:
print("false")
else:
# print true
if matrix[m - 1][(matLoc)] == 1:
print("true")
else:
# print false
print("false")
# Driver Code
if __name__ == "__main__":
stra = "GeeksForGeeks"
strb = "Geeks"
query = [0, 5, 8]
substringCheck(stra, strb, query)
C#
using System;
public class GFG {
private static void
substringCheck(string stra, string strb, int[] query)
{
// Dp Array
int[, ] matrix = new int[strb.Length, stra.Length];
// String to character array
char[] charCrr = stra.ToCharArray();
char[] charRrr = strb.ToCharArray();
// initialize matrix with 1
for (int c = 0; c < stra.Length; c++) {
if (charRrr[0] == charCrr[c]) {
matrix[0, c] = 1;
}
}
// for r from 1 to string length
for (int r = 1; r < charRrr.Length; r++) {
char ch = charRrr[r];
// for c from 1 b string length
for (int c = 1; c < charCrr.Length; c++) {
if (ch == charCrr[c]
&& matrix[r - 1, c - 1] == 1) {
matrix[r, c] = 1;
}
}
}
// For every query
foreach(int q in query)
{
int matLoc = (q + (strb.Length - 1));
if (matLoc >= stra.Length) {
Console.WriteLine(false);
}
else {
// print true
if (matrix[strb.Length - 1, matLoc] == 1) {
Console.WriteLine(true);
}
else {
// print false
Console.WriteLine(false);
}
}
}
}
// Driver Code
public static void Main(string[] args)
{
string stra = "GeeksForGeeks";
string strb = "Geeks";
int[] query = { 0, 5, 8 };
substringCheck(stra, strb, query);
}
}
// This code is contributed by ukasp.
JavaScript
<script>
function substringCheck(stra, strb, query)
{
// Dp Array
var matrix = Array.from(Array(strb.length), ()=>Array(stra.length));
// String to character array
var charCrr = stra.split('');
var charRrr = strb.split('');
// initialize matrix with 1
for (var c = 0; c < stra.length; c++)
{
if (charRrr[0] == charCrr[c])
{
matrix[0][c] = 1;
}
}
// for r from 1 to string length
for (var r = 1; r < charRrr.length; r++)
{
var ch = charRrr[r];
// for c from 1 b string length
for (var c = 1; c < charCrr.length; c++)
{
if (ch == charCrr[c]
&& matrix[r - 1][c - 1] == 1)
{
matrix[r][c] = 1;
}
}
}
// For every query
for (var q of query)
{
var matLoc = (q + (strb.length - 1));
if (matLoc >= stra.length) {
document.write(false + "<br>");
}
else
{
// print true
if (matrix[strb.length - 1][(matLoc)]
== 1)
{
document.write(true+ "<br>");
}
else
{
// print false
document.write(false+ "<br>");
}
}
}
}
// Driver Code
var stra = "GeeksForGeeks";
var strb = "Geeks";
var query = [0,5,8];
substringCheck(stra, strb, query);
// This code is contributed by rutvik_56.
</script>
Time Complexity: O(M*N)
Auxiliary Space: O(M*N)
Similar Reads
Check if the given string is shuffled substring of another string
Given strings str1 and str2. The task is to find if str1 is a substring in the shuffled form of str2 or not. Print "YES" if str1 is a substring in shuffled form of str2 else print "NO". Example Input: str1 = "onetwofour", str2 = "hellofourtwooneworld" Output: YES Explanation: str1 is substring in sh
15 min read
Check if two same sub-sequences exist in a string or not
Given a string, the task is to check if there exist two equal sub-sequences in the given string. Two sub-sequences are said to be equal if they have the same characters arranged in the same lexicographical order but the position of characters differs from that in the original string. Examples: Input
5 min read
Check if a string can be converted to another given string by removal of a substring
Given two strings S and T of length N and M respectively, the task is to check if the string S can be converted to the string T by removing at most one substring of the string S. If found to be true, then print âYESâ. Otherwise, print âNOâ. Example: Input: S = âabcdefâ, T = âabcâ Output: YES Explana
7 min read
Check if Prefix String exists in the Array
Given an array of strings, the task is to print "Yes" if it contains a string that is a prefix of another string otherwise, print "No". Examples: Input: arr[] = {"rud", "rudra", "rahi"}Output: YesExplanation: arr[0] = "rud" is a prefix of arr[1] = "rudra", that's why "Yes" is the output. Input: arr[
9 min read
Check if given string is a substring of string formed by repeated concatenation of z to a
Given a string str, the task is to check if string str is a substring of an infinite length string S in which lowercase alphabets are concatenated in reverse order as: S = "zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba...." Examples: Input: str = "cbaz"Output: YES Explanation:Given string "cb
10 min read
Check if two strings can be made equal by reversing a substring of one of the strings
Given two strings X and Y of length N, the task is to check if both the strings can be made equal by reversing any substring of X exactly once. If it is possible, then print "Yes". Otherwise, print "No". Examples: Input: X = "adcbef", Y = "abcdef"Output: YesExplanation: Strings can be made equal by
12 min read
Check if String Contains Substring in Python
This article will cover how to check if a Python string contains another string or a substring in Python. Given two strings, check whether a substring is in the given string. Input: Substring = "geeks" String="geeks for geeks"Output: yesInput: Substring = "geek" String="geeks for geeks"Output: yesEx
8 min read
Javascript Program To Check If A String Is Substring Of Another
Given two strings s1 and s2, find if s1 is a substring of s2. If yes, return the index of the first occurrence, else return -1. Examples :Â Input: s1 = "for", s2 = "geeksforgeeks" Output: 5 Explanation: String "for" is present as a substring of s2. Input: s1 = "practice", s2 = "geeksforgeeks" Output
2 min read
Check if a string is substring of another
Given two strings txt and pat, the task is to find if pat is a substring of txt. If yes, return the index of the first occurrence, else return -1.Examples : Input: txt = "geeksforgeeks", pat = "eks"Output: 2Explanation: String "eks" is present at index 2 and 9, so 2 is the smallest index.Input: txt
8 min read
Check if the string has a reversible equal substring at the ends
Given a string S consisting of N characters, the task is to check if this string has a reversible equal substring from the start and the end. If yes, print True and then the longest substring present following the given conditions, otherwise print False. Example: Input: S = "abca"Output: TrueaExplan
5 min read