# Maximum number of times a given string needs to be concatenated to form a substring of another string

• Difficulty Level : Medium
• Last Updated : 31 May, 2021

Given two strings S1 and S2 of length N and M respectively, the task is to find the maximum value of times the string S2 needs to be concatenated, such that it is a substring of the string S1.

Examples:

Input: S1 = “ababc”, S2 = “ab”
Output: 2
Explanation: After concatenating S2 exactly twice, the string modifies to “abab”. Therefore, string “abab” is a substring of “ababc”. Therefore, the result is 2.

Input: S1 = “ababc”, S2 = “ba”
Output: 1
Explanation: String “ba” is already a substring of “ababc”. Therefore, the result is 1.

Approach: To solve the given problem, the idea to use the KMP algorithm. Follow the steps below to solve the problem:

• Initialize a variable, say ans, to store the maximum value K such that concatenating S2 K times form a substring of the string S1.
• Initialize a string curWord and copy the contents of S2 in curWord.
• Store the maximum number of times a string can occur as numWords = N / M.
• Traverse the string over the indices [0, numWords – 1] and perform the following steps:
• If the value of curWord is found in string S1, then increment ans by 1 and concatenate curWord with the word.
• Otherwise, break out of the loop.
• After the above steps, print the value of ans as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find lps[] for given``// pattern pat[0..M-1]``void` `computeLPSArray(string pat, ``int` `M,``                     ``int``* lps)``{``    ``// Length of the previous``    ``// longest prefix suffix``    ``int` `len = 0;` `    ``// lps is always 0``    ``lps = 0;` `    ``// Iterate string to calculate lps[i]``    ``int` `i = 1;``    ``while` `(i < M) {` `        ``// If the current character``        ``// of the pattern matches``        ``if` `(pat[i] == pat[len]) {``            ``len++;``            ``lps[i] = len;``            ``i++;``        ``}` `        ``// Otherwise``        ``else` `{` `            ``if` `(len != 0) {` `                ``len = lps[len - 1];``            ``}` `            ``// Otherwise``            ``else` `{``                ``lps[i] = 0;``                ``i++;``            ``}``        ``}``    ``}``}` `// Function to implement KMP algorithm``int` `KMPSearch(string pat, string txt)``{``    ``int` `M = pat.size();``    ``int` `N = txt.size();` `    ``// Stores the longest prefix and``    ``// suffix values for pattern``    ``int` `lps[M];` `    ``// Preprocess the pattern and``    ``// find the lps[] array``    ``computeLPSArray(pat, M, lps);` `    ``// Index for txt[]``    ``int` `i = 0;` `    ``// Index for pat[]``    ``int` `j = 0;``    ``while` `(i < N) {` `        ``if` `(pat[j] == txt[i]) {``            ``j++;``            ``i++;``        ``}` `        ``// If pattern is found return 1``        ``if` `(j == M) {``            ``return` `1;``            ``j = lps[j - 1];``        ``}` `        ``// Mismatch after j matches``        ``else` `if` `(i < N``                 ``&& pat[j] != txt[i]) {` `            ``// Don't match lps[0, lps[j - 1]]``            ``// characters they will``            ``// match anyway``            ``if` `(j != 0)``                ``j = lps[j - 1];``            ``else``                ``i = i + 1;``        ``}``    ``}` `    ``// Return 0 if the pattern is not found``    ``return` `0;``}` `// Function to find the maximum value``// K for which string S2 concatenated``// K times is a substring of string S1``void` `maxRepeating(string seq, string word)``{``    ``// Store the required maximum number``    ``int` `resCount = 0;` `    ``// Create a temporary string to store``    ``// string word``    ``string curWord = word;` `    ``// Store the maximum number of times``    ``// string S2 can occur in string S1``    ``int` `numWords = seq.length() / word.length();` `    ``// Traverse in range[0, numWords-1]``    ``for` `(``int` `i = 0; i < numWords; i++) {` `        ``// If curWord is found in sequence``        ``if` `(KMPSearch(curWord, seq)) {` `            ``// Concatenate word to curWord``            ``curWord += word;` `            ``// Increment resCount by 1``            ``resCount++;``        ``}` `        ``// Otherwise break the loop``        ``else``            ``break``;``    ``}` `    ``// Print the answer``    ``cout << resCount;``}` `// Driver Code``int` `main()``{``    ``string S1 = ``"ababc"``, S2 = ``"ab"``;` `    ``// Function Call``    ``maxRepeating(S1, S2);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``class` `GFG``{``    ` `    ``// Function to find lps[] for given``    ``// pattern pat[0..M-1]``    ``static` `void` `computeLPSArray(String pat, ``int` `M,``                         ``int` `[]lps)``    ``{``        ``// Length of the previous``        ``// longest prefix suffix``        ``int` `len = ``0``;``    ` `        ``// lps is always 0``        ``lps[``0``] = ``0``;``    ` `        ``// Iterate string to calculate lps[i]``        ``int` `i = ``1``;``        ``while` `(i < M)``        ``{``    ` `            ``// If the current character``            ``// of the pattern matches``            ``if` `(pat.charAt(i) == pat.charAt(len))``            ``{``                ``len++;``                ``lps[i] = len;``                ``i++;``            ``}``    ` `            ``// Otherwise``            ``else``            ``{``                ``if` `(len != ``0``)``                ``{   ``                    ``len = lps[len - ``1``];``                ``}``    ` `                ``// Otherwise``                ``else``                ``{``                    ``lps[i] = ``0``;``                    ``i++;``                ``}``            ``}``        ``}``    ``}``    ` `    ``// Function to implement KMP algorithm``    ``static` `int` `KMPSearch(String pat, String txt)``    ``{``        ``int` `M = pat.length();``        ``int` `N = txt.length();``    ` `        ``// Stores the longest prefix and``        ``// suffix values for pattern``        ``int` `lps[] = ``new` `int``[M];``    ` `        ``// Preprocess the pattern and``        ``// find the lps[] array``        ``computeLPSArray(pat, M, lps);``    ` `        ``// Index for txt[]``        ``int` `i = ``0``;``    ` `        ``// Index for pat[]``        ``int` `j = ``0``;``        ``while` `(i < N)``        ``{   ``            ``if` `(pat.charAt(j) == txt.charAt(i))``            ``{``                ``j++;``                ``i++;``            ``}``    ` `            ``// If pattern is found return 1``            ``if` `(j == M)``            ``{``                ``return` `1``;``                ``//j = lps[j - 1];``            ``}``    ` `            ``// Mismatch after j matches``            ``else` `if` `(i < N``                     ``&& pat.charAt(j) != txt.charAt(i))``            ``{``    ` `                ``// Don't match lps[0, lps[j - 1]]``                ``// characters they will``                ``// match anyway``                ``if` `(j != ``0``)``                    ``j = lps[j - ``1``];``                ``else``                    ``i = i + ``1``;``            ``}``        ``}``    ` `        ``// Return 0 if the pattern is not found``        ``return` `0``;``    ``}``    ` `    ``// Function to find the maximum value``    ``// K for which string S2 concatenated``    ``// K times is a substring of string S1``    ``static` `void` `maxRepeating(String seq, String word)``    ``{``      ` `        ``// Store the required maximum number``        ``int` `resCount = ``0``;``    ` `        ``// Create a temporary string to store``        ``// string word``        ``String curWord = word;``    ` `        ``// Store the maximum number of times``        ``// string S2 can occur in string S1``        ``int` `numWords = seq.length() / word.length();``    ` `        ``// Traverse in range[0, numWords-1]``        ``for` `(``int` `i = ``0``; i < numWords; i++)``        ``{``    ` `            ``// If curWord is found in sequence``            ``if` `(KMPSearch(curWord, seq) == ``1``)``            ``{``    ` `                ``// Concatenate word to curWord``                ``curWord += word;``    ` `                ``// Increment resCount by 1``                ``resCount++;``            ``}``    ` `            ``// Otherwise break the loop``            ``else``                ``break``;``        ``}``    ` `        ``// Print the answer``        ``System.out.print(resCount);``    ``}``    ` `    ``// Driver Code``    ``public` `static` `void` `main (String[] args)``    ``{       ``        ``String S1 = ``"ababc"``, S2 = ``"ab"``;``    ` `        ``// Function Call``        ``maxRepeating(S1, S2);``    ``}``}` `// This code is contributed by AnkThon`

## Python3

 `# Python3 program for the above approach` `# Function to find lps[] for given``# pattern pat[0..M-1]``def` `computeLPSArray(pat, M, lps):``    ` `    ``# Length of the previous``    ``# longest prefix suffix``    ``lenn ``=` `0` `    ``# lps is always 0``    ``lps[``0``] ``=` `0` `    ``# Iterate string to calculate lps[i]``    ``i ``=` `1``    ``while` `(i < M):` `        ``# If the current character``        ``# of the pattern matches``        ``if` `(pat[i] ``=``=` `pat[lenn]):``            ``lenn ``+``=` `1``            ``lps[i] ``=` `lenn``            ``i ``+``=` `1``            ` `        ``# Otherwise``        ``else``:``            ``if` `(lenn !``=` `0``):``                ``lenn ``=` `lps[lenn ``-` `1``]``            ` `            ``# Otherwise``            ``else``:``                ``lps[i] ``=` `0``                ``i ``+``=` `1` `# Function to implement KMP algorithm``def` `KMPSearch(pat, txt):``    ``M ``=` `len``(pat)``    ``N ``=` `len``(txt)` `    ``# Stores the longest prefix and``    ``# suffix values for pattern``    ``lps ``=` `[``0` `for` `i ``in` `range``(M)]` `    ``# Preprocess the pattern and``    ``# find the lps[] array``    ``computeLPSArray(pat, M, lps)` `    ``# Index for txt[]``    ``i ``=` `0` `    ``# Index for pat[]``    ``j ``=` `0``    ``while` `(i < N):` `        ``if` `(pat[j] ``=``=` `txt[i]):``            ``j ``+``=` `1``            ``i ``+``=` `1` `        ``# If pattern is found return 1``        ``if` `(j ``=``=` `M):``            ``return` `1``            ``j ``=` `lps[j ``-` `1``]` `        ``# Mismatch after j matches``        ``elif` `(i < N ``and` `pat[j] !``=` `txt[i]):` `            ``# Don't match lps[0, lps[j - 1]]``            ``# characters they will``            ``# match anyway``            ``if` `(j !``=` `0``):``                ``j ``=` `lps[j ``-` `1``]``            ``else``:``                ``i ``=` `i ``+` `1` `    ``# Return 0 if the pattern is not found``    ``return` `0` `# Function to find the maximum value``# K for which S2 concatenated``# K times is a subof S1``def` `maxRepeating(seq, word):``    ` `    ``# Store the required maximum number``    ``resCount ``=` `0` `    ``# Create a temporary to store``    ``# word``    ``curWord ``=` `word` `    ``# Store the maximum number of times``    ``# S2 can occur in S1``    ``numWords ``=` `len``(seq) ``/``/` `len``(word)` `    ``# Traverse in range[0, numWords-1]``    ``for` `i ``in` `range``(numWords):` `        ``# If curWord is found in sequence``        ``if` `(KMPSearch(curWord, seq)):` `            ``# Concatenate word to curWord``            ``curWord ``+``=` `word` `            ``# Increment resCount by 1``            ``resCount ``+``=` `1` `        ``# Otherwise break the loop``        ``else``:``            ``break` `    ``# Print the answer``    ``print``(resCount)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``S1,S2 ``=` `"ababc"``,``"ab"` `    ``# Function Call``    ``maxRepeating(S1, S2)` `# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the above approach``using` `System;``class` `GFG``{``    ` `    ``// Function to find lps[] for given``    ``// pattern pat[0..M-1]``    ``static` `void` `computeLPSArray(String pat, ``int` `M,``                         ``int` `[]lps)``    ``{``        ``// Length of the previous``        ``// longest prefix suffix``        ``int` `len = 0;``    ` `        ``// lps is always 0``        ``lps = 0;``    ` `        ``// Iterate string to calculate lps[i]``        ``int` `i = 1;``        ``while` `(i < M)``        ``{``    ` `            ``// If the current character``            ``// of the pattern matches``            ``if` `(pat[i] == pat[len])``            ``{``                ``len++;``                ``lps[i] = len;``                ``i++;``            ``}``    ` `            ``// Otherwise``            ``else``            ``{``                ``if` `(len != 0)``                ``{   ``                    ``len = lps[len - 1];``                ``}``    ` `                ``// Otherwise``                ``else``                ``{``                    ``lps[i] = 0;``                    ``i++;``                ``}``            ``}``        ``}``    ``}``    ` `    ``// Function to implement KMP algorithm``    ``static` `int` `KMPSearch(String pat, String txt)``    ``{``        ``int` `M = pat.Length;``        ``int` `N = txt.Length;``    ` `        ``// Stores the longest prefix and``        ``// suffix values for pattern``        ``int` `[]lps = ``new` `int``[M];``    ` `        ``// Preprocess the pattern and``        ``// find the lps[] array``        ``computeLPSArray(pat, M, lps);``    ` `        ``// Index for txt[]``        ``int` `i = 0;``    ` `        ``// Index for pat[]``        ``int` `j = 0;``        ``while` `(i < N)``        ``{   ``            ``if` `(pat[j] == txt[i])``            ``{``                ``j++;``                ``i++;``            ``}``    ` `            ``// If pattern is found return 1``            ``if` `(j == M)``            ``{``                ``return` `1;``                ``//j = lps[j - 1];``            ``}``    ` `            ``// Mismatch after j matches``            ``else` `if` `(i < N``                     ``&& pat[j] != txt[i])``            ``{``    ` `                ``// Don't match lps[0, lps[j - 1]]``                ``// characters they will``                ``// match anyway``                ``if` `(j != 0)``                    ``j = lps[j - 1];``                ``else``                    ``i = i + 1;``            ``}``        ``}``    ` `        ``// Return 0 if the pattern is not found``        ``return` `0;``    ``}``    ` `    ``// Function to find the maximum value``    ``// K for which string S2 concatenated``    ``// K times is a substring of string S1``    ``static` `void` `maxRepeating(String seq, String word)``    ``{``      ` `        ``// Store the required maximum number``        ``int` `resCount = 0;``    ` `        ``// Create a temporary string to store``        ``// string word``        ``String curWord = word;``    ` `        ``// Store the maximum number of times``        ``// string S2 can occur in string S1``        ``int` `numWords = seq.Length / word.Length;``    ` `        ``// Traverse in range[0, numWords-1]``        ``for` `(``int` `i = 0; i < numWords; i++)``        ``{``    ` `            ``// If curWord is found in sequence``            ``if` `(KMPSearch(curWord, seq) == 1)``            ``{``    ` `                ``// Concatenate word to curWord``                ``curWord += word;``    ` `                ``// Increment resCount by 1``                ``resCount++;``            ``}``    ` `            ``// Otherwise break the loop``            ``else``                ``break``;``        ``}``    ` `        ``// Print the answer``        ``Console.Write(resCount);``    ``}``    ` `    ``// Driver Code``    ``public` `static` `void` `Main(String[] args)``    ``{       ``        ``String S1 = ``"ababc"``, S2 = ``"ab"``;``    ` `        ``// Function Call``        ``maxRepeating(S1, S2);``    ``}``}` `// This code is contributed by 29AjayKumar`

## Javascript

 ``

Output:

`2`

Time Complexity: O(N2)
Auxiliary Space: O(M)

My Personal Notes arrow_drop_up