Find minimum shift for longest common prefix - GeeksforGeeks

09 May, 2022
You are given two strings str1 and str2 of the same length. In a single shift, you can rotate one string (str2) by 1 element such that its 1st element becomes the last and the second one becomes the first like “abcd” will change to “bcda” after the one-shift operation. You have to find the minimum shift operation required to get the common prefix of maximum length from str1 and str2.Examples:  
Input : str1[] = "geeks", 
        str2 = "dgeek"
Output : Shift = 1, 
         Prefix = geek

Input : str1[] = "practicegeeks",
        str2 = "coderpractice"
Output : Shift = 5
         Prefix = practice
 
Naive Approach: Shift second string one by one and keep track of the length of the longest prefix for each shift, there is a total of n shifts and for each shift finding the length of the common prefix will take O(n) time. Hence, the overall time complexity for this approach is O(n^2). Better Approach: If we will add a second string at the end of itself that is str2 = str2 + str2 then there is no need of finding a prefix for each shift separately. Now, after adding str2 to itself we have to only find the longest prefix of str1 present in str2 and the starting position of that prefix in str2 will give us the actual number of shifts required. For finding the longest prefix we can use KMP pattern search algorithm. So, in this way, our time-complexity will reduce to O(n) only.  
C++
Java
Python3
C#
Javascript
// CPP program to find longest common prefix// after rotation of second string.#include <bits/stdc++.h>using namespace std; // function for KMP searchvoid 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 functionint main(){    string str1 = "geeksforgeeks";    string str2 = "forgeeksgeeks";    int n = str1.size();    str2 = str2 + str2;    KMP(2 * n, n, str2, str1);    return 0;}
// 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 program to find longest common prefix# after rotation of second string. # function for KMP searchdef 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             # print result    print("Shift = ", pos)    print("Prefix = ", str1[:Len]) # Driver Codestr1 = "geeksforgeeks"str2 = "forgeeksgeeks"n = len(str1)str2 = str2 + str2KMP(2 * n, n, str2, str1)     # This code is contributed by Mohit kumar 29
// 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 */
<script>  // Javascript program to find longest common prefix// after rotation of second string. // function for KMP searchfunction KMP(m, n, str2, str1){    var pos = 0, len = 0;     // preprocessing of longest proper prefix    var p = Array(m+1).fill(0);    var k = 0;    p[1] = 0;     for (var 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 (var 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    document.write( "Shift = " + pos + "<br>");    document.write( "Prefix = " + str1.substr(0, len));} // driver functionvar str1 = "geeksforgeeks";var str2 = "forgeeksgeeks";var n = str1.length;str2 = str2 + str2;KMP(2 * n, n, str2, str1);  </script>
Output:  
Shift = 8
Prefix = geeksforgeeks
 
mohit kumar 29
ukasp
princiraj1992
itsok
surinderdawra388
Pattern Searching
Strings
Strings
Pattern Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count N-length strings consisting only of vowels sorted lexicographically
Boyer Moore Algorithm | Good Suffix heuristic
Check whether two strings contain same characters in same order
How to check Aadhaar number is valid or not using Regular Expression
How to validate HTML tag using Regular Expression
Write a program to reverse an array or string
Reverse a string in Java
Write a program to print all permutations of a given string
C++ Data Types
Longest Common Subsequence | DP-4