Java中在字符串列表中查找公共子表达式的最有效方法

Java中在字符串列表中查找公共子表达式的最有效方法,java,arrays,algorithm,Java,Arrays,Algorithm,我有一个表示包目录的字符串列表。我想迭代列表,找到包相同的字符串的最大部分,然后提取这个子字符串,从原始字符串列表中减去它,得到特定的包,这样我就创建了相应的目录 我考虑将原始列表创建为一个静态哈希集,然后使用retainAll方法,将结果存储在一个新字符串中 这样的事情是最有效的选择,还是有更好的方法 非常感谢如果您正在寻找最常见的软件包,我将执行以下操作: 从列表中获取第一个元素(称之为参考包)。使用这个包名,我将遍历列表。对于列表中的每个剩余元素,请查看该元素是否包含引用包。如果是,则移动

我有一个表示包目录的字符串列表。我想迭代列表,找到包相同的字符串的最大部分,然后提取这个子字符串,从原始字符串列表中减去它,得到特定的包,这样我就创建了相应的目录

我考虑将原始列表创建为一个静态哈希集,然后使用retainAll方法,将结果存储在一个新字符串中

这样的事情是最有效的选择,还是有更好的方法


非常感谢

如果您正在寻找最常见的软件包,我将执行以下操作:

从列表中获取第一个元素(称之为参考包)。使用这个包名,我将遍历列表。对于列表中的每个剩余元素,请查看该元素是否包含引用包。如果是,则移动到下一个元素。如果没有,请将参考包裁剪为一个包(使用
aa.bb.cc.serverside
并转换为
aa.bb.cc
)。然后查看当前元素是否包含这个新的参考包。重复此操作,直到引用包为空或元素匹配为止。然后继续向下查看包列表

这将为您提供最大最常见的软件包。通过从列表中的所有元素中删除此项进行循环


编辑:稍加修改,最好将
保留在包名的末尾,以确保包名完整。

如果您只是在查找最常见的包,我将执行以下操作:

从列表中获取第一个元素(称之为参考包)。使用这个包名,我将遍历列表。对于列表中的每个剩余元素,请查看该元素是否包含引用包。如果是,则移动到下一个元素。如果没有,请将参考包裁剪为一个包(使用
aa.bb.cc.serverside
并转换为
aa.bb.cc
)。然后查看当前元素是否包含这个新的参考包。重复此操作,直到引用包为空或元素匹配为止。然后继续向下查看包列表

这将为您提供最大最常见的软件包。通过从列表中的所有元素中删除此项进行循环


编辑:稍加修改,最好将
保留在包名的末尾,以确保包名完整。

这对我很有用,请在注释中解释

// returns the length of the longest common prefix of all strings in the given array 
public static int longestCommonPrefix(String[] strings) {
    // Null or no contents, return 0
    if (strings == null || strings.length == 0) {
        return 0;
        // only 1 element? return it's length
    } else if (strings.length == 1 && strings[0] != null) {
        return strings[0].length();
        // more than 1
    } else {
        // copy the array and sort it on the lengths of the strings,
        // shortest one first.
        // this will raise a NullPointerException if an array element is null 
        String[] copy = Arrays.copyOf(strings, strings.length);
        Arrays.sort(copy, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.length() - o1.length();
            }
        });
        int result = 0; // init result
        // iterate through every letter of the shortest string
        for (int i = 0; i < copy[0].length(); i++) { 
            // compare the corresponding char of all other strings
            char currenChar = copy[0].charAt(i);
            for (int j = 1; j < strings.length; j++) {                  
                if (currenChar != copy[j].charAt(i)) { // mismatch
                    return result;
                }
            }
            // all match
            result++;
        }
        // done iterating through shortest string, all matched.
        return result;
    }
}
//返回给定数组中所有字符串的最长公共前缀的长度
公共静态int longestCommonPrefix(字符串[]字符串){
//Null或无内容,返回0
if(strings==null | | strings.length==0){
返回0;
//仅1个元素?返回其长度
}else if(strings.length==1&&strings[0]!=null){
返回字符串[0]。长度();
//超过1
}否则{
//复制数组并根据字符串的长度对其排序,
//首先是最短的一个。
//如果数组元素为null,则会引发NullPointerException
String[]copy=Arrays.copyOf(strings,strings.length);
sort(copy,newcomparator(){
@凌驾
公共整数比较(字符串o1、字符串o2){
返回o2.length()-o1.length();
}
});
int result=0;//初始化结果
//遍历最短字符串的每个字母
对于(int i=0;i
如果更改原始数组并不麻烦您,那么可以省略行
String[]copy=Arrays.copyOf(strings,strings.length)
并对
字符串进行排序


要检索文本,请将返回类型更改为
String
,并返回类似
returncopy[0]的内容。子字符串(0,result+1)在循环内,并
返回副本[0]在方法的末尾。

这对我很有效,在注释中解释

// returns the length of the longest common prefix of all strings in the given array 
public static int longestCommonPrefix(String[] strings) {
    // Null or no contents, return 0
    if (strings == null || strings.length == 0) {
        return 0;
        // only 1 element? return it's length
    } else if (strings.length == 1 && strings[0] != null) {
        return strings[0].length();
        // more than 1
    } else {
        // copy the array and sort it on the lengths of the strings,
        // shortest one first.
        // this will raise a NullPointerException if an array element is null 
        String[] copy = Arrays.copyOf(strings, strings.length);
        Arrays.sort(copy, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.length() - o1.length();
            }
        });
        int result = 0; // init result
        // iterate through every letter of the shortest string
        for (int i = 0; i < copy[0].length(); i++) { 
            // compare the corresponding char of all other strings
            char currenChar = copy[0].charAt(i);
            for (int j = 1; j < strings.length; j++) {                  
                if (currenChar != copy[j].charAt(i)) { // mismatch
                    return result;
                }
            }
            // all match
            result++;
        }
        // done iterating through shortest string, all matched.
        return result;
    }
}
//返回给定数组中所有字符串的最长公共前缀的长度
公共静态int longestCommonPrefix(字符串[]字符串){
//Null或无内容,返回0
if(strings==null | | strings.length==0){
返回0;
//仅1个元素?返回其长度
}else if(strings.length==1&&strings[0]!=null){
返回字符串[0]。长度();
//超过1
}否则{
//复制数组并根据字符串的长度对其排序,
//首先是最短的一个。
//如果数组元素为null,则会引发NullPointerException
String[]copy=Arrays.copyOf(strings,strings.length);
sort(copy,newcomparator(){
@凌驾
公共整数比较(字符串o1、字符串o2){
返回o2.length()-o1.length();
}
});
int result=0;//初始化结果
//遍历最短字符串的每个字母
对于(int i=0;i