2018年字节跳动 双生词

版权声明:原创文章,转载需注明转载出处! 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);
    }
}

猜你喜欢

转载自blog.csdn.net/zhoumingsong123/article/details/82056354