java中不使用库的n字符串的最长公共子序列?

java中不使用库的n字符串的最长公共子序列?,java,algorithm,Java,Algorithm,我试图找到一个简单的解决方案,我已经阅读了所有试图回答或解决问题的信息或问题,我正在测试。 我已经找到了一个从c#转换而来的解决方案,它可以工作,但是太复杂了,我不明白它是如何工作的,所以我试着制定我自己的解决方案 public static String lcs(String[] strings) { if (strings.length == 0) return "0"; if (strings.length == 1) r

我试图找到一个简单的解决方案,我已经阅读了所有试图回答或解决问题的信息或问题,我正在测试。 我已经找到了一个从c#转换而来的解决方案,它可以工作,但是太复杂了,我不明白它是如何工作的,所以我试着制定我自己的解决方案

public static String lcs(String[] strings) {
    if (strings.length == 0)
        return "0";
    if (strings.length == 1)
        return strings[0];
    int max = -1;//max length of a string
    int cacheSize = 1; //multiplied length size of array with each other.
    for (int i = 0; i < strings.length; i++) {
        cacheSize *= strings[i].length();
        if (strings[i].length() > max)
            max = strings[i].length();
    }
    String[] cache = new String[cacheSize];
    int[] indexes = new int[strings.length];
    for (int i = 0; i < indexes.length; i++)
        indexes[i] = strings[i].length() - 1;
    return lcsBack(strings, indexes, cache);
}

public static String lcsBack(String[] strings, int[] indexes, String[] cache) {
    for (int i = 0; i < indexes.length; i++)
        if (indexes[i] == -1)
            return "";
    boolean match = true;
    for (int i = 1; i < indexes.length; i++) {
        if (strings[0].charAt(indexes[0]) != strings[i].charAt(indexes[i])) {
            match = false;
            break;
        }
    }
    if (match) {
        int[] newIndexes = new int[indexes.length];
        for (int i = 0; i < indexes.length; i++)
            newIndexes[i] = indexes[i] - 1;
        String result = lcsBack(strings, newIndexes, cache) + strings[0].charAt(indexes[0]);
        cache[calcCachePos(indexes, strings)] = result;
        return result;
    } else {
        String[] subStrings = new String[strings.length];
        for (int i = 0; i < strings.length; i++) {
            if (indexes[i] <= 0)
                subStrings[i] = "";
            else {
                int[] newIndexes = new int[indexes.length];
                for (int j = 0; j < indexes.length; j++)
                    newIndexes[j] = indexes[j];
                newIndexes[i]--;
                int cachePos = calcCachePos(newIndexes, strings);
                if (cache[cachePos] == null)
                    subStrings[i] = lcsBack(strings, newIndexes, cache);
                else
                    subStrings[i] = cache[cachePos];
            }
        }
        String longestString = "";
        int longestlength = 0;
        for (int i = 0; i < subStrings.length; i++) {
            if (subStrings[i].length() > longestlength) {
                longestString = subStrings[i];
                longestlength = longestString.length();
            }
        }
        cache[calcCachePos(indexes, strings)] = longestString;
        return longestString;
    }
}

static int calcCachePos(int[] indexes, String[] strings) {
    int factor = 1;
    int pos = 0;
    for (int i = 0; i < indexes.length; i++) {
        pos += indexes[i] * factor;
        factor *= strings[i].length();
    }
    return pos;
}

您可能想发布实际的
findCommonSequence
code-您的
findCommonString
findTheLongTestString
与它的关系还不太清楚。另外,您的第二个单元测试总是会失败,因为“ACADB”和“CBDA”之间的最长子序列是“CB”、“CD”和“CA”之间的连接。您有我正在使用的两种方法,请仔细看看,我已经包含了它们,而“ACADB”和“CBDA”之间是CA的结果,很抱歉,这是一个输入错误,我现在将修复它。您的测试正确吗?“ACADB”和“CA”之间的注释子序列不应该是“CA”?在“ACADB”和“CBDA”之间,CA是结果,如果您正在测试,您可以使用我从c#翻译成java的代码,这是一个解决方案,我只尝试创建一个我了解其工作原理的解决方案
    /**
     * @param strArr .
     * @return String
     */
    public String findCommonString(String[] words) throws Exception {
        try {
            String commonStr = "";
            String tempCom = "";
            char[] longestWordChars = findTheLongestString(words).toCharArray();
            for (char c : longestWordChars) {
                tempCom += c;

                for (String word : words) {
                    if (!word.contains(tempCom)) {
                        tempCom = Character.toString(c);
                        for (String word2 : words) {
                            if (!word2.contains(tempCom)) {
                                tempCom = "";
                                break;
                            }
                        }
                        break;
                    }
                }

                if (tempCom != "" && tempCom.length()>commonStr.length()) {
                    commonStr = tempCom;
                    //strArr = removeFirstOccurrence(strArr, tempCom);
//                  tempCom = "";

                }
            }
            return commonStr;

        } catch (Exception e) {
            logger.warn("[findCommonString] [STATUS] - ERROR ");
            logger.warn("[findCommonString] [EXCEPTION] " + e.getMessage());
            throw e;
        }

    /**
     * @param strArr .
     * @return String
     */
    public String findTheLongestString(String[] words) throws Exception { // test
        try {
            String longestWord = "";

            for (String s : words) {
                if (longestWord.length() < s.length()) {
                    longestWord = s;
                }
            }
            return longestWord;

        } catch (Exception e) {
            logger.warn("[findTheLongestString] [STATUS] - ERROR ");
            logger.warn("[findTheLongestString] [EXCEPTION] " + e.getMessage());
            throw e;
        }
    }
@Test
public void SubsequenceServiceTest3() throws Exception {
    assertEquals("CDAC", subsequenceService.findCommonSequence(new String[] { "BCDAACD", "ACDBAC" }));
}

@Test
public void SubsequenceServiceTest14() throws Exception {
    assertEquals("CA", subsequenceService.findCommonSequence(new String[] { "ACADB", "CBDA" }));
}