Q:

# Longest Prefix and Suffix

Given a string of character, find the length of longest proper prefix which is also a proper suffix.

Input:

First line is T number of test cases. Each test case has one line denoting the string of length less than 100000.

Output:

Print length of longest proper prefix which is also a proper suffix.

Examples:

```    Input:
T = 1
"abcdabc"

Output:
3
//as prefix "abc" is the longest proper prefix
//present in the string.

Input:
T = 1
"abcdefghijklm"

Output:
0
//as there is no prefix which is a suffix.

Input:
T = 1
"aaaaaaa"

Output:
6
//as for proper prefix we can't have entire length
// as the prefix so only length possible is 6.```

1) Brute Force Approach

Since the longest proper prefix which is also a suffix cannot be equal to the entire length of the string because it can't overlap each other, so we break the string from mid-point and start matching left and right string. If they are equal return size of any one string else try for shorter lengths on both sides.

Pseudo Code:

```void solve(string str)
{
// declare two variable which will used for
// comparing two halfs of the string.
int i, j;
//store length in len variable.
int len = str.length();
i = len / 2; // initialise right half.
j = 0; // initialise left half.

// check if the right index variable
// is less than the length of the string.
while (i < len) {
// if the left half character is
// equal to right half characet.
is(str[i] == str[j])
{
// simply incres the pointers to compare next indexes.
i++;
j++;
continue;
}
else
{
// if the left half character is at start index
// and it is not equal to right half current
// character then increase

if (j == 0) { // right half index.
i++;
}
else { //search for lesser length of the prefix.
j--;
}
}
}
return j; //return length of prefix.
}
```

C++ Implementation:

``````#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
ll t;
cout << "Enter number of test cases: ";
cin >> t;

while (t--) {
cout << "Enter string: ";
string str;
cin >> str;

ll len = str.length();
// if length is less than one then
// simply length of lps is 0.

if (len <= 1) {
cout << 0 << "\n";
}
else {
ll i = len / 2; // initialise right half.
ll j = 0; // initialise left half.

// check if the right index variable is less
// than the length of the string.
while (i < len) {
// if the left half character is equal to
// right half characet.
if (str[i] == str[j]) {
i++;
j++;
}
else {
// if the left half character is at start index
// and it is not equal to right half current
// character then increase right half index.
if (j == 0)
i++;
else
j--; // search for lesser length of the prefix
}
}
cout << "Longest prefix-suffix length: ";
cout << j << "\n";
}
}

return 0;
}``````

Output

```Enter number of test cases: 3
Enter string: abcdabc
Longest prefix-suffix length: 3
Enter string: abcdefghabcdefgh
Longest prefix-suffix length: 8
Enter string: abcdefgh
Longest prefix-suffix length: 0
```

2) Better approach: Using longest prefix-suffix array of KMP algorithm

Here we will use an array which represents the length of the longest proper prefix which is also equal to the suffix of the array.

Here we use lps[] array which stores the length of a longest proper prefix which is the equal suffix, each index of lps represent the current index lps upto that index comparison, initialize lps=0, since it is not possible to have proper prefix-suffix with one letter then we declare two variable j and i by which we compare the characters.

Pseudo Code:

```int longestprefix(string str)
{
int len = str.length(); //len variable stores length of string.
int lps[len]; //declare lps array.
lps = 0; //single charater case so length lps is 0.
int i = 1; //initialise index for comparison from 1.
int j = 0; //initial longest prefix suffix length.
while (i < len) //check until i!=len of string.
{
//check current index character with character stored at j.
if (str[i] == str[j]) {
j++; //increase length by one.
lps[i] = j; //lps for current index is equal to j
i++; //move forward.
}
else //if str[i]!=str[j]
{
//we search for that index which character matches
//with the current character at index i.
if (j != 0) {
j = lps[j - 1];
}
else {
lps[i] = 0;
i++;
} //if j==0 then lps[i]=0.
}
}
return lps[j - 1]; //return lcs of given string.
}
```

C++ Implementation:

``````#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
ll t;
cout << "Enter number of test cases: ";
cin >> t;

while (t--) {
cout << "Enter string: ";
string str;
cin >> str;

ll len = str.length(); //len variable stores length of string.
ll lps[len]; //declare lps array.
lps = 0; //single charater case so length lps is 0.
ll i, j;
i = 1; //initialise index for comparison from 1.
j = 0; //initial longest prefix suffix length.

while (i < len) //check until i!=len of string.
{
//check current index character with character stored at j.
if (str[i] == str[j])
{
j++; //increase length by one.
lps[i] = j; //lps for current index is equal to j
i++; //move forward.
}
else //if str[i]!=str[j]
{
//we search for that index which character matches
//with the current character at index i.
if (j != 0)
j = lps[j - 1];
else {
lps[i] = 0; //if j==0 then lps[i]=0.
i++; //move forward.
}
}
}
cout << "Maximum length of proper prefix-suffix: ";
cout << lps[len - 1] << "\n";
}

return 0;
}``````

Output:

```Enter number of test cases: 3
Enter string: abcdefgh
Maximum length of proper prefix-suffix: 0
Enter string: abcdabc
Maximum length of proper prefix-suffix: 3
Enter string: abcdefghabcdefgh
Maximum length of proper prefix-suffix: 8```