現在給你乙個字串,請問在該字串末尾最少新增多少個字元,可以讓這個字串獲得重複迴圈序列。
輸入:第一行是乙個整數 t(0
<
t<
=100
)t ( 0t(
0<
t<=1
00) 代表測試資料的組數。之後t
tt行每行乙個字串,由小寫字母組成,字串的長度 3
<=l
<
=100000
3<=l<=100000
3<=l
<=1
0000
0。輸出:每組資料輸出一行結果。
樣例:
3
ppppip
machinelearning
0
115
思路:
迴圈節是指一段資料中重複的最小環。kmp不止要學會套模板匹配字串,還要學到kmp演算法的精髓——next陣列。
(未經優化的)nex
t[i]
next[i]
next[i
]指的 s[0
:i−1
]s[0:i-1]
s[0:i−
1]的最大共同前字尾長度(例如abcabcabc的共同前字尾為abcabc, abcabc為abc, abcabcabcabc為abc*3)
故一段字串的迴圈節就是: n−n
ext[
n]
n - next[n]
n−next
[n]將其記為len。若該字串是迴圈字串,則 n%l
en==
0n\%len==0
n%len=
=0, 而迴圈節的個數為:n/l
en
n/len
n/le
n若不是,則 nex
t[n]
==
0next[n] == 0
next[n
]==0
(abcd)或者n%l
en!=
0n\%len\ !=\ 0
n%len!
=0題解:
#include
#define maxn 1000005
using
namespace std;
int n;
char s[maxn]
;int next[maxm]
;int
getnext()
int len =
- next[n]
+ n;
if(next[n]==0
)return len;
//沒有迴圈部分,只能自身成為迴圈節
else
if(next[n]
%len==0)
return0;
//已經是迴圈字串
else
return len - next[n]
% len;
//需要補齊
}int
main()
return0;
}
給出乙個字串s(1為起始),問在[1, i]區間是否有完整的迴圈節,若有,輸出i並輸出迴圈次數
3
aaa12
aabaabaabaab
0
test case #1
2 23 3
test case #2
2 2 --aa(a)
6 2 --aabaab(aab)
9 3 --aabaabaab(aab)
12 4 --....
思路:求出next陣列後從1開始遍歷,若s[1
−i
]s[1-i]
s[1−i]
是迴圈字串則輸出 i
ii 和 n/l
en
n / len
n/len
題解:
#include
#define maxn 1000005
using
namespace std;
int n, kase=0;
char s[maxn]
;int next[maxn]
;void
getnext()
printf
("test case #%d\n"
,++kase)
;for
(int i=
2;i<=n;i++
)putchar
('\n');
}int
main()
return0;
}
對於字串a, 將其重複多次,形成新的字串aaa…aaaa,在其中擷取一段,作為b.
現給定b字串,求符合條件的最短的a
bcabcab
efgabcdefgabcde
3
7
思路:本題實際上就是在求b中的迴圈節長度,只不過前/後可以多/少一些部分,原來的方法依然是可求的。
**略
KMP演算法中的迴圈節問題
迴圈節問題包括 完全迴圈 和 不完全迴圈 對於乙個具有迴圈節並且長為n的字串,其迴圈節長為 n n x t n 1 並且滿足n n n x t n 1 0 這裡nxt 是kmp演算法中的next 陣列,並且是對於本部落格上上上篇給出的kmp模板的方法構造nxt陣列來說的。本篇部落格kmp演算法的講解...
最短迴圈節 KMP 實現
假設字串str的長度為len,則str存在最小迴圈節,迴圈節的長度cyclelen為len next len 迴圈子串為str 0 len next len 1 如果len可以被len next len 整除,則表明字串str可以完全由迴圈節迴圈組成 如果不能,說明還需要再新增幾個字母才能補全,需要...
kmp求最小迴圈節
kmp最小迴圈節 迴圈週期 定理 假設s的長度為len,則s存在最小迴圈節,迴圈節的長度l為len next len 子串為s 0 len next len 1 1 如果len可以被len next len 整除,則表明字串s可以完全由迴圈節迴圈組成,迴圈週期t len l。2 如果不能,說明還需要...