Check if given String is K-periodic for all K in range [1, N]
Last Updated :
29 Mar, 2022
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++
#include <iostream>
using namespace std;
void getZarr(string str, int Z[]);
void findPeriod(string text)
{
int l = text.length();
int Z[l];
getZarr(text, Z);
for ( int i = 1; i < l; ++i) {
if (Z[i] == (l - i))
cout << i << " " ;
}
cout << l << endl;
}
void getZarr(string str, int Z[])
{
int n = str.length();
int L, R, k;
L = R = 0;
for ( int i = 1; i < n; ++i) {
if (i > R) {
L = R = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
k = i - L;
if (Z[k] < R - i + 1)
Z[i] = Z[k];
else {
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
}
int main()
{
string text = "abcabca" ;
findPeriod(text);
return 0;
}
|
Java
class GFG {
public static void findPeriod(String text)
{
int l = text.length();
int Z[] = new int [l];
getZarr(text, Z);
for ( int i = 0 ; i < l; ++i) {
if (Z[i] == (l - i)) {
System.out.print(i + " " );
}
}
System.out.println(l);
}
private static void getZarr(String str, int [] Z)
{
int n = str.length();
int L = 0 , R = 0 ;
for ( int i = 1 ; i < n; ++i) {
if (i > R) {
L = R = i;
while (R < n && str.charAt(R - L) == str.charAt(R))
R++;
Z[i] = R - L;
R--;
}
else {
int k = i - L;
if (Z[k] < R - i + 1 )
Z[i] = Z[k];
else {
L = i;
while (R < n && str.charAt(R - L) == str.charAt(R))
R++;
Z[i] = R - L;
R--;
}
}
}
}
public static void main(String[] args)
{
String text = "abcabca" ;
findPeriod(text);
}
}
|
Python3
def getZarr( str , Z):
n = len ( str )
L, R, k = 0 , 0 , 0
for i in range ( 1 , n):
if (i > R):
L = R = i
while (R < n and str [R - L] = = str [R]):
R + = 1
Z[i] = R - L
R - = 1
else :
k = i - L
if (Z[k] < R - i + 1 ):
Z[i] = Z[k]
else :
L = i
while (R < n and str [R - L] = = str [R]):
R + = 1
Z[i] = R - L
R - = 1
def findPeriod(text):
l = len (text)
Z = [ 0 for _ in range (l)]
getZarr(text, Z)
for i in range ( 1 , l):
if (Z[i] = = (l - i)):
print (i, end = " " )
print (l)
if __name__ = = "__main__" :
text = "abcabca"
findPeriod(text)
|
C#
using System;
class GFG {
static void findPeriod( string text)
{
int l = text.Length;
int [] Z = new int [l];
getZarr(text, Z);
for ( int i = 1; i < l; ++i) {
if (Z[i] == (l - i))
Console.Write(i + " " );
}
Console.WriteLine(l);
}
static void getZarr( string str, int [] Z)
{
int n = str.Length;
int L, R, k;
L = R = 0;
for ( int i = 1; i < n; ++i) {
if (i > R) {
L = R = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
k = i - L;
if (Z[k] < R - i + 1)
Z[i] = Z[k];
else {
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
}
public static int Main()
{
string text = "abcabca" ;
findPeriod(text);
return 0;
}
}
|
Javascript
<script>
function getZarr(str, Z)
{
let n = str.length;
let L, R, k;
L = R = 0;
for (let i = 1; i < n; ++i) {
if (i > R) {
L = R = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
else {
k = i - L;
if (Z[k] < R - i + 1)
Z[i] = Z[k];
else {
L = i;
while (R < n && str[R - L] == str[R])
R++;
Z[i] = R - L;
R--;
}
}
}
}
function findPeriod(text)
{
let l = text.length;
let Z= new Array(l);
getZarr(text, Z);
for (let i = 1; i < l; ++i) {
if (Z[i] == (l - i))
document.write(i + " " )
}
document.write(l + '<br>')
}
let text = "abcabca" ;
findPeriod(text);
</script>
|
Time complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...