检查给定字符串是否对范围 [1, N] 中的所有 K 都是 K 周期的
给定一个大小为N的字符串str ,任务是检查给定字符串是否为K -periodic ,对于范围[1, N]中的所有 K。如果给定字符串是K-periodic则打印Yes ,否则打印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.
例子:
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.
方法:可以使用z 算法解决该任务。
- 让我们为给定的字符串构造 Z 数组。 (0索引)
- 然后,i 是一个句点,(Ni) 应该等于索引 i 处的 z 值,因为如果 'i' 是字符串的句点之一,那么长度 (Ni) 的后缀与长度的前缀完全匹配(你)。
- 最后,将 N(字符串的长度)附加到答案中,N 值是微不足道的,上面提到的方法找不到。
下面是上述方法的实现:
C++
// C++ code for the above approach:
#include
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;
}
Java
// 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);
}
}
C#
// 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
Javascript
3 6 7
时间复杂度: O(N)
辅助空间: O(N)