LCS与后缀数组

前一段时间的 LCS问题

LCS 问题及其扩展,找到多个字符串的所有公共子串

用后缀树的方法 ,看了编程珠玑后觉得后缀树组更简洁高效 ,故重新实现下


找出单个字符串最长的重复子串以及最长的出现m次的子串。

 

import java.util.ArrayList;
import java.util.Collections;

/**

 * User: yiminghe
 * Date: 2009-3-2
 * Time: 23:36:32

 */
public class LCS {


    //得到单词的后缀树组并按照字母顺序排序
    private static ArrayList<String> getSuffixArray(String s) {
        ArrayList<String> al = new ArrayList<String>();
        int l = s.length();
        for (int i = 0; i < l; i++) {
            al.add(s.substring(i));
        }


        Collections.sort(al);
        return al;
    }


    /**
     * @param s 字符串
     * @return 最长的重复m次字符串
     */
    public static String getLongestCommonSubstring(String s, int m) {
        String longStr = "";
        String[] suffixes = getSuffixArray(s).toArray(new String[0]);
        for (int i = 0; i < suffixes.length - (m - 1); i++) {
            int tl = getCommonLength(suffixes, i, i + m - 1);
            if (tl > longStr.length())
                longStr = suffixes[i].substring(0, tl);
        }
        return longStr;


    }

    //得到n个单词相同的位数
    private static int getCommonLength(String[] s, int start, int end) {
        int c = 0;

        while (true) {
            for (int i = start; i <= end; i++)
                if (s[i].length() <= c) return c;
            for (int i = start; i < end; i++)
                if (s[i].charAt(c) != s[i + 1].charAt(c)) return c;
            ++c;
        }

    }


    public static void main(String[] args) {
        String test = "banana";
        System.out.println(getLongestCommonSubstring(test,3));
    }
}
 

 

 

 

 


你可能感兴趣的:(编程,C++,c,C#)