求两个字符串的最大公共长度 看到的一道阿里笔试题

来源:互联网 发布:男生知乎 编辑:程序博客网 时间:2024/05/17 14:30

题目:给定一个query和一个text,均由小写字母组成。要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度。例如, query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3。请注意程序效率。


我的思路是:假设短的那个字符串为s,求从下标i = 0 为起点的子串用KMP算法求其和长串的最大公共长度max,再求i=1时的max,一直到s.length - max。此后无需再继续,因为结果一定小于max。

代码如下:

publicclass FindMaxMatch {
 
       int max= 0;// 最大已匹配长度
       int index= -1;//已匹配字符串的起点
 
       /**
        * 获得匹配数组
        */
       publicstaticint[] getNext(char[]pattern) {
              if (null== pattern || pattern.length< 2) {
                     System.out.println("Error. no need for KMP");
                     returnnull;
              }
 
              int[] next =newint[pattern.length];
              next[0]= -1;
              next[1]= 0;
              int k = 0;
              int i = 1;
              while (i < pattern.length - 1) {
                     if (pattern[i] == pattern[next[i]])
                            next[i]= next[next[i]];
                     if (pattern[i] == pattern[k]) {
                            next[i+ 1] = k + 1;
                            k++;
                            i++;
                     }elseif (k != 0)
                            k= 0;
                     else {
                            next[i+ 1] = 0;
                            i++;
                     }
              }
              if (pattern[i] == pattern[next[i]])
                     next[i]= next[next[i]];
              return next;
       }
 
       publicvoid find(String pattern, String query) {
              char[] qr = query.toCharArray();
              int len = pattern.length();
 
              //从i开始的每个子串的最大匹配长度i>len-max时无需再查找
              for (inti = 0; i < len - max&&max < len; i++) {
                     char[] pt = pattern.substring(i).toCharArray();
                     int[] next =getNext(pt);
 
                     int k = 0;
                     int j = 0;
                     while (j < qr.length&& k < pt.length){
                            if (qr[j] == pt[k]) {
                                   k++;
                                   j++;
                            }else {
                                   if (k  >max){//记录已匹配的最大长度
                                          max = k ;
                                          index = j - k;
                                   }
                                   k= next[k];
                                   if (k == -1) {
                                          k= 0;
                                          j++;
                                   }
                            }
                     }
                     if (k == pt.length){
                            max = k;
                            index = j - k;
                     }
              }
       }
 
       publicstaticvoid main(String[] args) {
              Strings = "sfdabcdaabcabead";
              Stringq = "seedsdagdafasghfadshbagfsdnhbadghsrtjhnaasdgas  fasfdabcdaabcaquery";
              FindMaxMatch a = new FindMaxMatch();
              a.find(s,q);
              System.out.println(q.substring(a.index, a.max+ a.index) +"  "
                            +a.index +"   "+ a.max);
       }
}

运行结果是:

sfdabcdaabc  51   11


使用前应判断长串和短串。我就不修改了。


0 0
原创粉丝点击