📌  相关文章
📜  查找最长的公共前缀的最小移位

📅  最后修改于: 2021-04-28 00:16:13             🧑  作者: Mango

您将获得两个长度相同的字符串str1和str2。在单个移位中,您可以将一个字符串(str2)旋转1个元素,以使其第一个元素变为最后一个元素,第二个元素变为第一个元素,例如在进行一次移位操作后,“ abcd”将变为“ bcda”。您必须找到从str1和str2获得最大长度的公共前缀所需的最小移位操作。

例子:

Input : str1[] = "geeks", 
        str2 = "dgeek"
Output : Shift = 1, 
         Prefix = geek

Input : str1[] = "practicegeeks",
        str2 = "coderpractice"
Output : Shift = 5
         Prefix = practice

天真的方法:逐个移位第二个字符串,并跟踪每个移位的最长前缀的长度,总共有n个移位,并且对于每个移位,找到公共前缀的长度将花费O(n)时间。因此,该方法的总时间复杂度为O(n ^ 2)。
更好的方法:如果我们将在其末尾添加第二个字符串,即str2 = str2 + str2,则无需分别为每个移位查找前缀。现在,在将str2添加到自身之后,我们仅需要找到str2中存在的最长的str1前缀,并且该前缀在str2中的起始位置将为我们提供所需的实际移位数。为了找到最长的前缀,我们可以使用KMP模式搜索算法。
因此,通过这种方式,我们的时间复杂度将仅降低到O(n)。

C++
// CPP program to find longest common prefix
// after rotation of second string.
#include 
using namespace std;
  
// function for KMP search
void KMP(int m, int n, string str2, string str1)
{
    int pos = 0, len = 0;
  
    // preprocessing of longest proper prefix
    int p[m + 1];
    int k = 0;
    p[1] = 0;
  
    for (int i = 2; i <= n; i++) {
        while (k > 0 && str1[k] != str1[i - 1])
            k = p[k];
        if (str1[k] == str1[i - 1])
            ++k;
        p[i] = k;
    }
  
    // find out the longest prefix and position
    for (int j = 0, i = 0; i < m; i++) {
        while (j > 0 && str1[j] != str2[i])
            j = p[j];
        if (str1[j] == str2[i])
            j++;
  
        // for new position with longer prefix in str2
        // update pos and len
        if (j > len) {
            len = j;
            pos = i - j + 1;
        }
    }
  
    // print result
    cout << "Shift = " << pos << endl;
    cout << "Prefix = " << str1.substr(0, len);
}
  
// driver function
int main()
{
    string str1 = "geeksforgeeks";
    string str2 = "forgeeksgeeks";
    int n = str1.size();
    str2 = str2 + str2;
    KMP(2 * n, n, str2, str1);
    return 0;
}


Java
// Java program to find longest common prefix
// after rotation of second string.
  
class GFG {
  
    // function for KMP search
    static void KMP(int m, int n, 
                    String str2, String str1)
    {
        int pos = 0, len = 0;
        int []p = new int[m + 1];
        int k = 0;
  
        //p[1] = 0;
        char []ch1 = str1.toCharArray();
        char []ch2 = str2.toCharArray();
  
        for (int i = 2; i <= n; i++)
        {
            while (k > 0 && ch1[k] != ch1[i - 1])
                k = p[k];
            if (ch1[k] == ch1[i - 1])
                ++k;
            p[i] = k;
        }
  
        // find out the longest prefix and position
        for (int j = 0, i = 0; i < m; i++) 
        {
            while (j > 0 && j < n && ch1[j] != ch2[i])
                j = p[j];
            if (j < n && ch1[j] == ch2[i])
                j++;
      
            // for new position with longer prefix in str2
            // update pos and len
            if (j > len)
            {
                len = j;
                pos = i - j + 1;
            }
        }
  
            // print result
            System.out.println("Shift = " + pos);
            System.out.println("Prefix = " + 
                                str1.substring(0,len));
        }
  
    // Driver code
    public static void main(String[] args) 
    {
        String str1 = "geeksforgeeks";
        String str2 = "forgeeksgeeks";
        int n = str1.length();
        str2 = str2 + str2;
        KMP(2 * n, n, str2, str1);
    }
}
  
// This code is contributed by Ita_c.


Python3
# Python3 program to find longest common prefix
# after rotation of second string.
  
# function for KMP search
def KMP(m, n, str2, str1):
  
    pos = 0
    Len = 0
  
    # preprocessing of longest proper prefix
    p = [0 for i in range(m + 1)]
    k = 0
  
    for i in range(2, n + 1): 
        while (k > 0 and str1[k] != str1[i - 1]):
            k = p[k]
        if (str1[k] == str1[i - 1]):
            k += 1
        p[i] = k
      
  
    # find out the longest prefix and position
    j = 0
    for i in range(m):
        while (j > 0 and j < n and str1[j] != str2[i]):
            j = p[j]
        if (j < n and str1[j] == str2[i]):
            j += 1
   
        # for new position with longer prefix 
        # in str2 update pos and Len
        if (j > Len): 
            Len = j
            pos = i - j + 1
          
    # prresult
    print("Shift = ", pos)
    print("Prefix = ", str1[:Len])
  
# Driver Code
str1 = "geeksforgeeks"
str2 = "forgeeksgeeks"
n = len(str1)
str2 = str2 + str2
KMP(2 * n, n, str2, str1)
      
# This code is contributed by Mohit kumar 29


C#
// C# program to find longest common prefix
// after rotation of second string.
using System;
      
class GFG {
   
    // function for KMP search
    static void KMP(int m, int n, 
                    String str2, String str1)
    {
        int pos = 0, len = 0;
        int []p = new int[m + 1];
        int k = 0;
   
        //p[1] = 0;
        char []ch1 = str1.ToCharArray();
        char []ch2 = str2.ToCharArray();
   
        for (int i = 2; i <= n; i++)
        {
            while (k > 0 && ch1[k] != ch1[i - 1])
                k = p[k];
            if (ch1[k] == ch1[i - 1])
                ++k;
            p[i] = k;
        }
   
        // find out the longest prefix and position
        for (int j = 0, i = 0; i < m; i++) 
        {
            while (j > 0 && j < n && ch1[j] != ch2[i])
                j = p[j];
            if (j < n && ch1[j] == ch2[i])
                j++;
       
            // for new position with longer prefix in str2
            // update pos and len
            if (j > len)
            {
                len = j;
                pos = i - j + 1;
            }
        }
   
            // print result
            Console.WriteLine("Shift = " + pos);
            Console.WriteLine("Prefix = " + 
                                str1.Substring(0,len));
        }
   
    // Driver code
    public static void Main(String[] args) 
    {
        String str1 = "geeksforgeeks";
        String str2 = "forgeeksgeeks";
        int n = str1.Length;
        str2 = str2 + str2;
        KMP(2 * n, n, str2, str1);
    }
}
  
/* This code contributed by PrinciRaj1992 */


输出:

Shift = 8
Prefix = geeksforgeeks