版权声明:原创文章,转载需注明转载出处! https://blog.csdn.net/zhoumingsong123/article/details/82056354
import java.util.*;
public class Main{
public static void main(String [] args)
{
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
outer:
for(int i=0;i<t;i++)
{
int n=sc.nextInt();
String var[]=new String[n];
for(int j=0;j<n;j++)
{
var[j]=sc.next();
}
for(int j=0;j<n;j++)
{
for(int q=j+1;q<n;q++)
{
boolean flag=judge(var[j]+var[j],var[q]);
//本来使用的是讲字符串n个位置切开,然后顺序和逆序和目标字符串
//对比,时间复杂度为O(n^4);
//这里改良了,把两个var[j]复制一份,var[q]如果是双生词的话
//var[q]必定是var[j]+var[j]的子串,然后使用kmp匹配。
//复杂度降为O(n^3)
if(flag)
{
System.out.println("Yeah");
continue outer;
}
}
}
System.out.println("Sad");
}
}
private static boolean judge(String str, String patternStr) {
int pai[] = new int[patternStr.length() + 1];//pai是模式p的后缀 pai[q]=max{k,k<q且pk是pq的后缀//算法导论}//pk 表示p[1...k]
char pattern[] = new char[patternStr.length() + 1];
for (int i = 1; i < pattern.length; i++) {
pattern[i] = patternStr.charAt(i - 1);//pattern[0]不使用
}
computePai(pai, pattern);
boolean flag = matchStr(pai, str, pattern);
if (flag) {
return true;
} else {
return false;
}
}
private static boolean matchStr(int[] pai, String str, char[] pattern) {
int i = 0;
int q = 0;
while (i < str.length()) {
while (q > 0 && str.charAt(i) != pattern[q + 1])//
{
q = pai[q];
}
if (str.charAt(i) == pattern[q + 1]) {
q++;
}
if (q == pattern.length - 1) {//index=0没有用
return true;
//look another match
//q=pai[q];
}
i++;
}
return false;
}
private static void computePai(int[] pai, char[] pattern) {
pai[1] = 0;
int k = 0;//k is pai[q-1] k+1 is pattern compare index
for (int q = 2; q < pai.length; q++) {//pai[q-1]=wPk
while (k > 0 && pattern[k + 1] != pattern[q])//当pai*[q-1]不为空 ,pai[q]=1+max{pai*[q-1]} 否则pai[k]=0(即pai[1]=0)
{
k = pai[k];//k>pai[k]
}
//k=0 or pattern.charAt(k+1)=pattern.charAt(q)
if (pattern[k + 1] == pattern[q])//p[k+1]=p[q]
{
k = k + 1;
}
pai[q] = k;
}
}
private static String getStr1(int index, String str) {//
int count=0;
int i=index;
char array[]=new char[str.length()];
while (count<str.length())
{
array[count]=str.charAt((i+str.length())%str.length());
i++;
count++;
}
return String.valueOf(array);
}
private static String getStr2(int index, String str) {
int count=0;
int i=index-1;
char array[]=new char[str.length()];
while (count<str.length())
{
array[count]=str.charAt((i+str.length())%str.length());
i--;
count++;
}
return String.valueOf(array);
}
}