📜  给定字符串形成另一个字符串的子字符串所需的最大次数

📅  最后修改于: 2021-04-24 21:30:39             🧑  作者: Mango

给定分别具有长度NM的两个字符串S1S2 ,任务是查找需要串联字符串S2的次数的最大值,以使其成为字符串S1的子字符串。

例子:

方法:为了解决给定的问题,使用KMP算法的想法。请按照以下步骤解决问题:

  • 初始化一个变量,例如ans ,以存储最大值K ,以便将S2 K次串联形成字符串S1的子字符串。
  • 初始化字符串curWord并在curWord中复制S2的内容。
  • numWords = N / M的形式存储一个字符串可以出现的最大次数。
  • 在索引[0,numWords – 1]上遍历字符串然后执行以下步骤:
    • 如果在字符串S1中找到curWord的值,则将ans递增1并将curWord单词连接。
    • 否则,请跳出循环。
  • 完成上述步骤后,将ans的值打印为结果。

下面是上述方法的实现:

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[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


输出:
2

时间复杂度: O(N 2 )
辅助空间: O(M)