Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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 <bits/stdc++.h>
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[0] 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[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[0] 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[0] 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[0] 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[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




<script>
 
// JavaScript program for the above approach
 
// Function to find lps[] for given
// pattern pat[0..M-1]
function computeLPSArray(pat, M, lps)
{
    // Length of the previous
    // longest prefix suffix
    var len = 0;
 
    // lps[0] is always 0
    lps[0] = 0;
 
    // Iterate string to calculate lps[i]
    var 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
function KMPSearch(pat, txt)
{
    var M = pat.length;
    var N = txt.length;
 
    // Stores the longest prefix and
    // suffix values for pattern
    var lps = Array(M);
 
    // Preprocess the pattern and
    // find the lps[] array
    computeLPSArray(pat, M, lps);
 
    // Index for txt[]
    var i = 0;
 
    // Index for pat[]
    var 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
function maxRepeating(seq, word)
{
    // Store the required maximum number
    var resCount = 0;
 
    // Create a temporary string to store
    // string word
    var curWord = word;
 
    // Store the maximum number of times
    // string S2 can occur in string S1
    var numWords = seq.length / word.length;
 
    // Traverse in range[0, numWords-1]
    for (var 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
    document.write( resCount);
}
 
// Driver Code
var S1 = "ababc", S2 = "ab";
 
// Function Call
maxRepeating(S1, S2);
 
 
</script>


 
 

Output: 

2

 

 

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

 



Last Updated : 31 May, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads