Given a string str of size N, the task is to check whether the given string is K-periodic, for all Ks in range [1, N]. Print Yes if the given string is K-periodic, else print No.
A string is K-periodic, if the string is a repetition of the sub-string str[0 … k-1].
For example, the string “ababab” is 2-periodic.
Examples:
Input: N = 7, S = “abcabca”
Output: 3 6 7
Explanation:
1. Consider prefix of length 1 (i.e. “a”), then if we repeat this prefix to make a string of length 7, we get “aaaaaaa” which is not equal to the original string.
2. Consider prefix of length 2 (i.e. “ab”), then if we repeat this prefix to make a string of length 7, we get “abababa” which is not equal to the original string.
3. Consider prefix of length 3 (i.e. “abc”), then if we repeat this prefix to make a string of length 7, we get “abcabca” which is equal to the original string.
4. Consider prefix of length 4 (i.e. “abca”), then if we repeat this prefix to make a string of length 7, we get “abcaabc” which is not equal to the original string.
5. Consider prefix of length 5 (i.e. “abcab”), then if we repeat this prefix to make a string of length 7, we get “abcabab” which is not equal to the original string.
6. Consider prefix of length 6 (i.e. “abcabc”), then if we repeat this prefix to make a string of length 7, we get “abcabca” which is equal to the original string.
7. Consider prefix of length 7 (i.e. “abcabca”), then if we repeat this prefix to make a string of length 7, we get “abcabca” which is equal to the original string.Input: N = 5, S = “aaaaa”
Output: 1 2 3 4 5
Explanation: As all the characters of the given string are same hence, the string can be generated by repeating the prefix of length 1 to N.
Approach: The task can be solved using z-algorithm.
- Let’s construct Z array for the given string. (0-indexed)
- Then, i to be a period, (N-i) should be equal to the z value at index i, because if ‘i’ is one of the period of the string, then a suffix of length (N-i) exactly matches with prefix of length (n-i).
- At last, append N (length of the string) to the answer, the N value is trivial which the above mentioned method doesn’t find.
Below is the implementation of the above approach:
// C++ code for the above approach: #include <iostream> using namespace std;
void getZarr(string str, int Z[]);
// Prints all the period of a string void findPeriod(string text)
{ int l = text.length();
// Construct Z array
int Z[l];
getZarr(text, Z);
// Now looping through Z array
// For finding period
for ( int i = 1; i < l; ++i) {
// If(l-i) is equal to Z[i],
// Then one of the period
// Of string is i
if (Z[i] == (l - i))
cout << i << " " ;
}
// Print trivial value
//(i.e. length of string)
cout << l << endl;
} // Fills Z array for given string str[] void getZarr(string str, int Z[])
{ int n = str.length();
int L, R, k;
// [L, R] make a window
// Which matches with prefix of s
L = R = 0;
for ( int i = 1; i < n; ++i) {
// If i>R nothing matches
// So we will calculate.
// Z[i] using naive way.
if (i > R) {
L = R = i;
// R-L = 0 in starting, so it will start
// Checking from 0'th index. For example,
// For "ababab" and i = 1, the value of R
// Remains 0 and Z[i] becomes 0. For string
// "aaaaaa" and i = 1, Z[i] and R become 5
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
// k = i-L so k corresponds to number
// Which matches in [L, R] interval.
k = i - L;
// If Z[k] is less than remaining interval
// Then Z[i] will be equal to Z[k].
// For example, str = "ababab", i = 3, R = 5
// and L = 2
if (Z[k] < R - i + 1)
Z[i] = Z[k];
// For example str = "aaaaaa"
// and i = 2, R is 5, L is 0
else {
// Else start from R
// And check manually
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
} // Driver code int main()
{ string text = "abcabca" ;
findPeriod(text);
return 0;
} |
// A Java program that implements Z algorithm for period // finding class GFG {
// prints all the period of string
public static void findPeriod(String text)
{
int l = text.length();
int Z[] = new int [l];
// Construct Z array
getZarr(text, Z);
// now looping through Z array for finding period
for ( int i = 0 ; i < l; ++i) {
// if Z[i] is equal to (l-i), then one
// of the period of string is i
if (Z[i] == (l - i)) {
System.out.print(i + " " );
}
}
// Print trivial value (i.e. length of string)
System.out.println(l);
}
// Fills Z array for given string str[]
private static void getZarr(String str, int [] Z)
{
int n = str.length();
// [L, R] make a window which matches with
// prefix of s
int L = 0 , R = 0 ;
for ( int i = 1 ; i < n; ++i) {
// if i>R nothing matches so we will calculate.
// Z[i] using naive way.
if (i > R) {
L = R = i;
// R-L = 0 in starting, so it will start
// checking from 0'th index. For example,
// for "ababab" and i = 1, the value of R
// remains 0 and Z[i] becomes 0. For string
// "aaaaaa" and i = 1, Z[i] and R become 5
while (R < n && str.charAt(R - L) == str.charAt(R))
R++;
Z[i] = R - L;
R--;
}
else {
// k = i-L so k corresponds to number which
// matches in [L, R] interval.
int k = i - L;
// if Z[k] is less than remaining interval
// then Z[i] will be equal to Z[k].
// For example, str = "ababab", i = 3, R = 5
// and L = 2
if (Z[k] < R - i + 1 )
Z[i] = Z[k];
// For example str = "aaaaaa" and i = 2, R is 5,
// L is 0
else {
// else start from R and check manually
L = i;
while (R < n && str.charAt(R - L) == str.charAt(R))
R++;
Z[i] = R - L;
R--;
}
}
}
}
// Driver program
public static void main(String[] args)
{
String text = "abcabca" ;
findPeriod(text);
}
} |
# python3 code for the above approach: # Fills Z array for given string str[] def getZarr( str , Z):
n = len ( str )
L, R, k = 0 , 0 , 0
# [L, R] make a window
# Which matches with prefix of s
for i in range ( 1 , n):
# If i>R nothing matches
# So we will calculate.
# Z[i] using naive way.
if (i > R):
L = R = i
# R-L = 0 in starting, so it will start
# Checking from 0'th index. For example,
# For "ababab" and i = 1, the value of R
# Remains 0 and Z[i] becomes 0. For string
# "aaaaaa" and i = 1, Z[i] and R become 5
while (R < n and str [R - L] = = str [R]):
R + = 1
Z[i] = R - L
R - = 1
else :
# k = i-L so k corresponds to number
# Which matches in [L, R] interval.
k = i - L
# If Z[k] is less than remaining interval
# Then Z[i] will be equal to Z[k].
# For example, str = "ababab", i = 3, R = 5
# and L = 2
if (Z[k] < R - i + 1 ):
Z[i] = Z[k]
# For example str = "aaaaaa"
# and i = 2, R is 5, L is 0
else :
# Else start from R
# And check manually
L = i
while (R < n and str [R - L] = = str [R]):
R + = 1
Z[i] = R - L
R - = 1
# Prints all the period of a string def findPeriod(text):
l = len (text)
# Construct Z array
Z = [ 0 for _ in range (l)]
getZarr(text, Z)
# Now looping through Z array
# For finding period
for i in range ( 1 , l):
# If(l-i) is equal to Z[i],
# Then one of the period
# Of string is i
if (Z[i] = = (l - i)):
print (i, end = " " )
# Print trivial value
# (i.e. length of string)
print (l)
# Driver code if __name__ = = "__main__" :
text = "abcabca"
findPeriod(text)
# This code is contributed by rakeshsahni |
// C# code for the above approach: using System;
class GFG {
// Prints all the period of a string
static void findPeriod( string text)
{
int l = text.Length;
// Construct Z array
int [] Z = new int [l];
getZarr(text, Z);
// Now looping through Z array
// For finding period
for ( int i = 1; i < l; ++i) {
// If(l-i) is equal to Z[i],
// Then one of the period
// Of string is i
if (Z[i] == (l - i))
Console.Write(i + " " );
}
// Print trivial value
//(i.e. length of string)
Console.WriteLine(l);
}
// Fills Z array for given string str[]
static void getZarr( string str, int [] Z)
{
int n = str.Length;
int L, R, k;
// [L, R] make a window
// Which matches with prefix of s
L = R = 0;
for ( int i = 1; i < n; ++i) {
// If i>R nothing matches
// So we will calculate.
// Z[i] using naive way.
if (i > R) {
L = R = i;
// R-L = 0 in starting, so it will start
// Checking from 0'th index. For example,
// For "ababab" and i = 1, the value of R
// Remains 0 and Z[i] becomes 0. For string
// "aaaaaa" and i = 1, Z[i] and R become 5
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
// k = i-L so k corresponds to number
// Which matches in [L, R] interval.
k = i - L;
// If Z[k] is less than remaining interval
// Then Z[i] will be equal to Z[k].
// For example, str = "ababab", i = 3, R = 5
// and L = 2
if (Z[k] < R - i + 1)
Z[i] = Z[k];
// For example str = "aaaaaa"
// and i = 2, R is 5, L is 0
else {
// Else start from R
// And check manually
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
}
// Driver code
public static int Main()
{
string text = "abcabca" ;
findPeriod(text);
return 0;
}
} // This code is contributed by Taranpreet |
<script> // JavaScript code for the above approach
// Fills Z array for given string str[] function getZarr(str, Z)
{ let n = str.length;
let L, R, k;
// [L, R] make a window
// Which matches with prefix of s
L = R = 0;
for (let i = 1; i < n; ++i) {
// If i>R nothing matches
// So we will calculate.
// Z[i] using naive way.
if (i > R) {
L = R = i;
// R-L = 0 in starting, so it will start
// Checking from 0'th index. For example,
// For "ababab" and i = 1, the value of R
// Remains 0 and Z[i] becomes 0. For string
// "aaaaaa" and i = 1, Z[i] and R become 5
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
// k = i-L so k corresponds to number
// Which matches in [L, R] interval.
k = i - L;
// If Z[k] is less than remaining interval
// Then Z[i] will be equal to Z[k].
// For example, str = "ababab", i = 3, R = 5
// and L = 2
if (Z[k] < R - i + 1)
Z[i] = Z[k];
// For example str = "aaaaaa"
// and i = 2, R is 5, L is 0
else {
// Else start from R
// And check manually
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
} // Prints all the period of a string function findPeriod(text)
{ let l = text.length;
// Construct Z array
let Z= new Array(l);
getZarr(text, Z);
// Now looping through Z array
// For finding period
for (let i = 1; i < l; ++i) {
// If(l-i) is equal to Z[i],
// Then one of the period
// Of string is i
if (Z[i] == (l - i))
document.write(i + " " )
}
// Print trivial value
//(i.e. length of string)
document.write(l + '<br>')
} // Driver code let text = "abcabca" ;
findPeriod(text);
// This code is contributed by Potta Lokesh
</script>
|
3 6 7
Time complexity: O(N)
Auxiliary Space: O(N)