查找所有长度至少为2个字符的常见子字符串

时间:2019-06-03 14:38:25

标签: java algorithm

任务的内容:

查找所有(从最长,最短结尾开始)最小长度为2个字符的公共子字符串,这些子字符串与先前找到的子字符串不重叠。

我的任务是重新制作以下代码或编写新代码。我什至不知道如何开始:/

public static void main(String[] args) {
        String text1 = "AABABB";
        String text2 = "BAABAB";

        int len1 = text1.length();
        int len2 = text2.length();

        int max = 0;
        int position_w1 = -1;
        int position_w2 = -1;

        for (int i = 0; i < len1 - max; i++)
        {

            for (int k = len2 - 1; k >= 0; k--)
            {
                int counter = 0;
                int limit = Math.min(len2, (len1 -i + k) );  
                for (int j = k; j < limit; j++)
                {
                    if (text1.charAt(i+j-k) == text2.charAt(j)) 
                    {                        
                        counter++;

                        if (max < counter) 
                        {
                            max = counter;
                            position_w1 = i + j - k - max + 1;
                            position_w2 = j - max + 1;
                        }
                    }
                    else counter = 0;
                }
            }
        }

        System.out.println("Position of text1: " + position_w1 + ", position of text2: " + position_w2 + ", length: " + max);



        System.out.println(text1.substring(0, position_w1) + "\u001B[31m" 
                + text1.substring(position_w1, max + position_w1) + "\u001B[0m" + text1.substring(max + position_w1) );
        System.out.println(text2.substring(0, position_w2) + "\u001B[31m" 
                + text2.substring(position_w2, max + position_w2) + "\u001B[0m" + text2.substring(max + position_w2) );
    }

2 个答案:

答案 0 :(得分:0)

也许尝试这样的事情:

public static void main(String[] args){
    String text1 = "AABABB";
    String text2 = "BAABAB";

    int maxLen = 3;

    for (int len = 2; len < maxLen; len++) {
        ArrayList<Pair<Integer, Integer>> intervalsText1 = new ArrayList<>();
        ArrayList<Pair<Integer, Integer>> intervalsText2 = new ArrayList<>();

        for (int i = 0; i < text1.length() - len; i++) { 
            String sub1 = text1.substring(i, i + len);

            for (int j = 0; j < text2.length() - len; i++) {
                String sub2 = text2.substring(j, j + len);

                if(sub1.equals(sub2)){
                    //check if overlapping
                    for(Pair<Integer, Integer> inter : intervalsText1){
                        for(Pair<Integer, Integer> inter : intervalsText1){
                            if(!isInsideInterval(inter, i) && !isInsideInterval(inter, i + len)){
                                if(!isInsideInterval(inter, j) && !isInsideInterval(inter, j + len)){ 
                                    //the strings are equal and outside previous strings
                                    intervalsText1.add(Pair.of(i, i + len));
                                    intervalsText2.add(Pair.of(j, j + len));
                                }
                            }   
                        }
                    }
                }
            }
        }
    }
}

public static boolean isInsideInterval(Pair<Integer, Integer> interval, int toCheck){
    if(interval.getLeft() < toCheck && interval.getRight() > toCheck)
        return true;

    return false;
}

*请注意,我尚未检查它是否有效

答案 1 :(得分:0)

这是家庭作业,只需一些精神帮助。

立即进入类似于for-i的循环很难阅读和/或更改。

考虑如何自己完成任务,看看原始作者做了什么。

从最大子序列开始,将是:

int max = Math.min(len1, len2);
...
--max;

甚至

for (int max = Math.min(len1, len2); may > 0; --max) {
    for (int i = 0; i + max <= len1; ++i) {
         if (match found) {
             print match;
             i += max - 1;
         }
    }
}

for-k循环执行--k;有点不必要的恕我直言。

匹配子字符串,并在匹配时被i += max;i += max - 1;跳过,将会受益于String.substring或您自己的函数。

顺便说一句,当准备就绪时,请考虑一下诸如跳过第二次查找的子字符串之类的事情:“ AB”在text1中出现两次。好名字很重要,评论可能会有所帮助。否则可能会违反“环境代码”的规定。

         int notEarlierPos = text1.indexOf(text1.subtring(i, i + max));
         if (notEarlierPos == i) { // Not already treated earlier.
             int matchPos = text2.indexOf(text1.subtring(i, i + max));
             if (matchPos != -1) {
                 print match;
                 i += max - 1;
             }
         }