Longest prefix which is also suffix
Given a string s, find the length of the longest prefix, which is also a suffix. The prefix and suffix should not overlap.
Examples:
Input : aabcdaabc Output : 4 The string "aabc" is the longest prefix which is also suffix. Input : abcab Output : 2 Input : aaaa Output : 2
Simple Solution: Since overlapping prefixes and suffixes is not allowed, we break the string from the middle and start matching left and right strings. If they are equal return size of one string, else they try for shorter lengths on both sides.
Below is a solution to the above approach!
C++
// CPP program to find length of the // longest prefix which is also suffix #include <bits/stdc++.h> using namespace std; // Function to find largest prefix // which is also a suffix int largest_prefix_suffix( const std::string &str) { int n = str.length(); // if n is less than 2 if (n < 2) { return 0; } int len = 0; int i = 1; // Iterate i till n while (i < n) { // If str[i] is equal to // str[len] if (str[i] == str[len]) { ++len; ++i; } else { i = i - len + 1; len = 0; } } // Return len return len>n/2? len/2:len; } // Driver code int main() { string s = "blablabla" ; // Function Call cout << largest_prefix_suffix(s); return 0; } |
C
#include <stdio.h> #include <string.h> int largest_prefix_suffix( const char * str) { int n = strlen (str); // If n is less than 2 if (n < 2) { return 0; } int len = 0; int i = 1; // Iterate i till n while (i < n) { // If str[i] is equal to str[len] if (str[i] == str[len]) { ++len; ++i; } else { i = i - len + 1; len = 0; } } // Return len return len > n / 2 ? len / 2 : len; } int main() { const char * s = "blablabla" ; // Function Call printf ( "%d\n" , largest_prefix_suffix(s)); return 0; } |
Java
// Java program to find length of the longest // prefix which is also suffix class GFG { // Function to find largest prefix // which is also a suffix static int longestPrefixSuffix(String s) { int n = s.length(); // If n is less than 2 if (n < 2 ) { return 0 ; } int len = 0 ; int i = (n + 1 )/ 2 ; // Iterate i till n while (i < n) { // If s.charAt(i) is equal to // s.charAt(len) if (s.charAt(i) == s.charAt(len)) { ++len; ++i; } else { i = i - len + 1 ; len = 0 ; } } // Return len return len; } // Driver code public static void main (String[] args) { String s = "abcaabc" ; System.out.println(longestPrefixSuffix(s)); } } // This code is contributed by Anant Agarwal. |
Python3
# Python3 program to find length # of the longest prefix which # is also suffix def longestPrefixSuffix(s) : n = len (s) for res in range (n / / 2 , 0 , - 1 ) : # Check for shorter lengths # of first half. prefix = s[ 0 : res] suffix = s[n - res: n] if (prefix = = suffix) : return res # if no prefix and suffix match # occurs return 0 # Driver Code if __name__ = = "__main__" : s = "blablabla" print (longestPrefixSuffix(s)) # This code is contributed by Nikita Tiwari. |
Javascript
<script> // JavaScript program to find length of the longest // prefix which is also suffix // Function to find largest prefix // which is also a suffix function longestPrefixSuffix(s) { var n = s.length; // If n is less than 2 if (n < 2) { return 0; } var len = 0; var i = (n + 1)/2; // Iterate i till n while (i < n) { // If s[i] is equal to // s[len] if (s[i] == s[len]) { ++len; ++i; } else { i = i - len + 1; len = 0; } } // Return len return len; } // Driver code var s = "blablabla" ; document.write(longestPrefixSuffix(s)); // This code contributed by shikhasingrajput </script> |
C#
// C# program to find length of the longest // prefix which is also suffix using System; class GFG { // Function to find largest prefix // which is also a suffix static int longestPrefixSuffix(String s) { int n = s.Length; // if n is less than 2 if (n < 2) { return 0; } int len = 0; int i = (n + 1)/2; // Iterate i till n while (i < n) { // If str[i] is equal to // str[len] if (str[i] == str[len]) { ++len; ++i; } else { i = i - len + 1; len = 0; } } // Return len return len; } // Driver code public static void Main () { String s = "blablabla" ; Console.WriteLine(longestPrefixSuffix(s)); } } // This code is contributed by vt_m. |
3
Time Complexity: O(n)
Auxiliary Space: O(1)
Efficient Solution: The idea is to use the preprocessing algorithm KMP search. In the preprocessing algorithm, we build lps array which stores the following values.
lps[i] = the longest proper prefix of pat[0..i]
which is also a suffix of pat[0..i].
C
#include <stdio.h> #include <string.h> int longestPrefixSuffix( const char * s) { int n = strlen (s); int lps[n]; lps[0] = 0; // lps[0] is always 0 int len = 0; int i = (n + 1) / 2; while (i < n) { if (s[i] == s[len]) { len++; lps[i] = len; i++; } else { if (len != 0) { len = lps[len - 1]; } else { lps[i] = 0; i++; } } } int res = lps[n - 1]; return res; } int main() { const char * s = "bbabbabb" ; printf ( "%d\n" , longestPrefixSuffix(s)); return 0; } |
C++
// Efficient CPP program to find length of // the longest prefix which is also suffix #include<bits/stdc++.h> using namespace std; // Returns length of the longest prefix // which is also suffix and the two do // not overlap. This function mainly is // copy computeLPSArray() of in below post int longestPrefixSuffix(string s) { int n = s.length(); int lps[n]; lps[0] = 0; // lps[0] is always 0 // length of the previous // longest prefix suffix int len = 0; // the loop calculates lps[i] // for i = 1 to n-1 int i = (n+1)/2; while (i < n) { if (s[i] == s[len]) { len++; lps[i] = len; i++; } else // (pat[i] != pat[len]) { // This is tricky. Consider // the example. AAACAAAA // and i = 7. The idea is // similar to search step. if (len != 0) { len = lps[len-1]; // Also, note that we do // not increment i here } else // if (len == 0) { lps[i] = 0; i++; } } } int res = lps[n-1]; // Since we are looking for // non overlapping parts. return res; } // Driver program to test above function int main() { string s = "bbabbabb" ; cout << longestPrefixSuffix(s); return 0; } // Corrected by Nilanshu Yadav |
Java
// Efficient Java program to find length of // the longest prefix which is also suffix class GFG { // Returns length of the longest prefix // which is also suffix and the two do // not overlap. This function mainly is // copy computeLPSArray() of in below post // for-patterns-set-2-kmp-algorithm/ static int longestPrefixSuffix(String s) { int n = s.length(); int lps[] = new int [n]; // lps[0] is always 0 lps[ 0 ] = 0 ; // length of the previous // longest prefix suffix int len = 0 ; // the loop calculates lps[i] // for i = 1 to n-1 int i = (n+ 1 )/ 2 ; while (i < n) { if (s.charAt(i) == s.charAt(len)) { len++; lps[i] = len; i++; } // (pat[i] != pat[len]) else { // This is tricky. Consider // the example. AAACAAAA // and i = 7. The idea is // similar to search step. if (len != 0 ) { len = lps[len- 1 ]; // Also, note that we do // not increment i here } // if (len == 0) else { lps[i] = 0 ; i++; } } } int res = lps[n- 1 ]; // Since we are looking for // non overlapping parts. return res; } // Driver program public static void main (String[] args) { String s = "bbabbabb" ; System.out.println(longestPrefixSuffix(s)); } } // This code is contributed by Anant Agarwal. // Corrected by Nilanshu Yadav |
Python3
# Efficient Python 3 program # to find length of # the longest prefix # which is also suffix # Returns length of the longest prefix # which is also suffix and the two do # not overlap. This function mainly is # copy computeLPSArray() of in below post def longestPrefixSuffix(s) : n = len (s) lps = [ 0 ] * n # lps[0] is always 0 # length of the previous # longest prefix suffix l = 0 # the loop calculates lps[i] # for i = 1 to n-1 i = (n + 1 ) / / 2 ; while (i < n) : if (s[i] = = s[l]) : l = l + 1 lps[i] = l i = i + 1 else : # (pat[i] != pat[len]) # This is tricky. Consider # the example. AAACAAAA # and i = 7. The idea is # similar to search step. if (l ! = 0 ) : l = lps[l - 1 ] # Also, note that we do # not increment i here else : # if (len == 0) lps[i] = 0 i = i + 1 res = lps[n - 1 ] # Since we are looking for # non overlapping parts. return res; # Driver program to test above function s = "bbabbabb" print (longestPrefixSuffix(s)) # This code is contributed # by Nikita Tiwari. #Corrected by Nilanshu Yadav |
Javascript
<script> // Efficient javascript program to find length of // the longest prefix which is also suffix{ // Returns length of the longest prefix // which is also suffix and the two do // not overlap. This function mainly is // copy computeLPSArray() of in below post // for-patterns-set-2-kmp-algorithm/ function longestPrefixSuffix(s) { var n = s.length; var lps = Array.from({length: n}, (_, i) => 0); // lps[0] is always 0 lps[0] = 0; // length of the previous // longest prefix suffix var len = 0; // the loop calculates lps[i] // for i = 1 to n-1 var i = 1; while (i < n) { if (s.charAt(i) == s.charAt(len)) { len++; lps[i] = len; i++; } // (pat[i] != pat[len]) else { // This is tricky. Consider // the example. AAACAAAA // and i = 7. The idea is // similar to search step. if (len != 0) { len = lps[len-1]; // Also, note that we do // not increment i here } // if (len == 0) else { lps[i] = 0; i++; } } } var res = lps[n-1]; // Since we are looking for // non overlapping parts. return (res > n/2)? n/2 : res; } // Driver program var s = "abcab" ; document.write(longestPrefixSuffix(s)); // This code is contributed by 29AjayKumar </script> |
C#
// Efficient C# program to find length of // the longest prefix which is also suffix using System; class GFG { // Returns length of the longest prefix // which is also suffix and the two do // not overlap. This function mainly is // copy computeLPSArray() of in below post // for-patterns-set-2-kmp-algorithm/ static int longestPrefixSuffix( string s) { int n = s.Length; int []lps = new int [n]; // lps[0] is always 0 lps[0] = 0; // length of the previous // longest prefix suffix int len = 0; // the loop calculates lps[i] // for i = 1 to n-1 int i = 1; while (i < n) { if (s[i] == s[len]) { len++; lps[i] = len; i++; } // (pat[i] != pat[len]) else { // This is tricky. Consider // the example. AAACAAAA // and i = 7. The idea is // similar to search step. if (len != 0) { len = lps[len-1]; // Also, note that we do // not increment i here } // if (len == 0) else { lps[i] = 0; i++; } } } int res = lps[n-1]; // Since we are looking for // non overlapping parts. return (res > n/2) ? n/2 : res; } // Driver program public static void Main () { string s = "abcab" ; Console.WriteLine(longestPrefixSuffix(s)); } } // This code is contributed by vt_m. |
PHP
<?php // Efficient PHP program to find length of // the longest prefix which is also suffix // Returns length of the longest prefix // which is also suffix and the two do // not overlap. This function mainly is // copy computeLPSArray() of in below post function longestPrefixSuffix( $s ) { $n = strlen ( $s ); $lps [ $n ] = NULL; // lps[0] is always 0 $lps [0] = 0; // length of the previous // longest prefix suffix $len = 0; // the loop calculates lps[i] // for i = 1 to n-1 $i = 1; while ( $i < $n ) { if ( $s [ $i ] == $s [ $len ]) { $len ++; $lps [ $i ] = $len ; $i ++; } // (pat[i] != pat[len]) else { // This is tricky. Consider // the example. AAACAAAA // and i = 7. The idea is // similar to search step. if ( $len != 0) { $len = $lps [ $len -1]; // Also, note that we do // not increment i here } // if (len == 0) else { $lps [ $i ] = 0; $i ++; } } } $res = $lps [ $n -1]; // Since we are looking for // non overlapping parts. return ( $res > $n /2)? $n /2 : $res ; } // Driver Code $s = "abcab" ; echo longestPrefixSuffix( $s ); // This code is contributed by nitin mittal ?> |
2
Time Complexity: O(n)
Auxiliary Space: O(n)
Please refer computeLPSArray() of KMP search for an explanation.
Solution using RegEx:
C++
#include <iostream> #include <regex> // Required for std::regex and std::smatch int main() { std::string s = "ABCABCABCABCABC" ; // Example input std::regex regex( "^(\\w*).*\\1$" ); // Define the regular expression std::smatch match; // Define a match object to store the matched string if (std::regex_search(s, match, regex)) { // Search for a match in the string std::cout << match.str(1).length() << std::endl; // Output the length of the first capturing group } return 0; } |
Java
import java.util.regex.Matcher; import java.util.regex.Pattern; public class GFG { public static void main(String[] args) { String s = "ABCABCABCABCABC" ; // Example input String regex = "^(\\w*).*\\1$" ; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(s); if (matcher.find()) { System.out.println(matcher.group( 1 ).length()); } } } |
Python3
# Python code to find length of the longest # prefix which is also suffix import re s = "ABCABCABCABCABC" # Example input print ( len (re.findall(r '^(\w*).*\1$' ,s)[ 0 ])) |
Javascript
const s = "ABCABCABCABCABC" ; // Example input const regex = new RegExp(`^(\\w*).*\\1$`); const match = s.match(regex); console.log(match[1].length); // THIS CODE IS CONTRIBUTED BY CHANDAN AGARWAL |
6
The time and space complexity of this program depend on the size of the input string and the complexity of the regular expression.
Assuming the input string has length n, the time complexity of std::regex_search function is typically O(n) on most modern regex engines, but can be worse in some cases. The time complexity of the std::string::length() function is O(1). Therefore, the overall time complexity of this program is O(n).
The space complexity of the program is mainly determined by the size of the match object std::smatch. The space required by std::smatch depends on the number of captured subgroups in the regular expression and the size of the input string. In this case, the regular expression has one capturing group, so the space complexity is proportional to the size of the input string. Therefore, the space complexity of the program is O(n).
Efficient Solution: The idea is to traverse the suffix in reverse order and try to find a match in first half of the string (possible prefix). Here we take advantage of the property of a prefix substring – when traversed in reverse order, the prefix substring’s last character will always terminate at the string’s beginning.
Please note that we search for the prefix in the first half of the string alone because of the constraint given in the problem that the prefix and suffix are non-overlapping.
Algorithm :
1. Maintain two pointers – one which starts at the end of string(for suffix) and one which starts at the middle of string(for prefix)
2. Keep on decrementing both the pointers provided they match and the prefix pointer is not exhausted( >0) .
3. When a mismatch occurs, reset the suffix pointer back to end of string and repeat step 2.
4. When prefix pointer reaches ‘-1’ (i.e. string is exhausted) the longest common suffix/prefix will be the substring from suffix pointer
to end of the string. Return the length of this substring.
Implementation:
C++
#include<iostream> #include<string> using namespace std; int longestPrefixSuffix(string s){ int n = s.length(); if (n == 0){ return 0; } int end_suffix = n-1; int end_prefix = n/2 - 1; while (end_prefix >= 0){ if (s[end_prefix] != s[end_suffix]){ if (end_suffix != n-1){ end_suffix = n-1; } else { end_prefix -= 1; } } else { end_suffix -= 1; end_prefix -= 1; } } return n-end_suffix-1; } int main(){ string s = "ABCABCABCABCABC" ; cout<<longestPrefixSuffix(s)<<endl; return 0; } |
Python3
# Python3 program to find length # of the longest prefix which # is also suffix # Returns length of the longest prefix # which is also suffix and the two do # not overlap. def longestPrefixSuffix(s): n = len (s) if n = = 0 : return 0 # end_suffix and end_prefix are used to keep track of the common suffix and prefix respectively. # For the prefix we search only in first half of string (0-->n//2-1) since # suffix and prefix do not overlap. end_suffix = n - 1 end_prefix = n / / 2 - 1 # Traverse each character of suffix from end to start and check for a match of prefix # in first half of array. while end_prefix > = 0 : if s[end_prefix] ! = s[end_suffix]: if end_suffix ! = n - 1 : end_suffix = n - 1 # reset end_suffix else : end_prefix - = 1 else : end_suffix - = 1 end_prefix - = 1 # The longest common suffix and prefix is s[end+1:] return n - end_suffix - 1 # Driver Code if __name__ = = "__main__" : s = "ABCABCABCABCABC" print (longestPrefixSuffix(s)) # This code is contributed by Reshma Koshy. |
Javascript
// JavaScript program to find length // of the longest prefix which // is also suffix // Returns length of the longest prefix // which is also suffix and the two do // not overlap. function longestPrefixSuffix(s) { let n = s.length; if (n === 0) { return 0; } // end_suffix and end_prefix are used to keep track of the common suffix and prefix respectively. // For the prefix we search only in first half of string (0-->n//2-1) since // suffix and prefix do not overlap. let end_suffix = n - 1; let end_prefix = Math.floor(n / 2) - 1; // Traverse each character of suffix from end to start and check for a match of prefix // in first half of array. while (end_prefix >= 0) { if (s[end_prefix] !== s[end_suffix]) { if (end_suffix !== n - 1) { end_suffix = n - 1; // reset end_suffix } else { end_prefix -= 1; } } else { end_suffix -= 1; end_prefix -= 1; } } // The longest common suffix and prefix is s[end+1:] return n - end_suffix - 1; } // Driver Code let s = "ABCABCABCABCABC" ; console.log(longestPrefixSuffix(s)); |
6
Time Complexity: O(n)
Auxiliary Space: O(1)
Please Login to comment...