Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取子序列匹配中的索引列表_Java - Fatal编程技术网

Java 获取子序列匹配中的索引列表

Java 获取子序列匹配中的索引列表,java,Java,我有两个序列,例如s=aaba和ss=aa,我想要ss在s中的所有方式。 在本例中: [0,1]、[0,3]和[1,3] 我的代码如下。它工作得很好,除了有多个ss的非常长的s。那样的话,我有 主线程java.lang.OutOfMemoryError中出现异常:超出GC开销限制 我已经在最大限度上使用了带-Xmx的java public static ArrayList<ArrayList<Integer>> getListIndex(String[] s, Strin

我有两个序列,例如s=aaba和ss=aa,我想要ss在s中的所有方式。 在本例中: [0,1]、[0,3]和[1,3] 我的代码如下。它工作得很好,除了有多个ss的非常长的s。那样的话,我有

主线程java.lang.OutOfMemoryError中出现异常:超出GC开销限制 我已经在最大限度上使用了带-Xmx的java

public static ArrayList<ArrayList<Integer>> getListIndex(String[] s, String[] ss, int is, int iss) {
    ArrayList<ArrayList<Integer>> listOfListIndex = new ArrayList<ArrayList<Integer>>();
    ArrayList<ArrayList<Integer>> listRec = new ArrayList<ArrayList<Integer>>();
            ArrayList<Integer> listI = new ArrayList<Integer>();

    if (iss<0||is<iss){
        return listOfListIndex;
    }

    if (ss[iss].compareTo(s[is])==0){

        //ss[iss] matches, search ss[0..iss-1] in s[0..is-1]
        listRec = getListIndex(s,ss,is-1,iss-1);

        //empty lists (iss=0 for instance)
        if(listRec.size()==0){
            listI = new  ArrayList<Integer>();
            listI.add(is);
            listOfListIndex.add(listI);
        }
        else{
            //adding to what we have already found
            for (int i=0; i<listRec.size();i++){
                listI = listRec.get(i);
                    listI.add(is);
                    listOfListIndex.add(listI);
            }
        }
    }
    //In all cases
    //searching ss[0..iss] in s[0..is-1]
    listRec = getListIndex(s,ss,is-1,iss);
    for (int i=0; i<listRec.size();i++){
        listI = listRec.get(i);
            listOfListIndex.add(listI);
    }

    return listOfListIndex;
}   

还有什么方法可以更有效地执行此操作吗?

好吧,基本问题是您的算法是递归的。Java不进行尾部调用优化,所以每次递归调用只会添加到堆栈中,直到溢出为止

你要做的是重新构造你的算法,使之适合你,这样你就不会添加到堆栈中。考虑将带有终止测试的循环作为方法的最外层元素

看待此问题的另一种方法是将其分为两个步骤:

将示例中所有给定字符“a”的位置捕捉到单个集合中。 这里您只需要它们之间的完整组合。记住,从n个不同事物中选择的r个事物的组合数的等式是:

 C(n,r) = n!/[r!(n-r)!]

由于包装器类的开销,ArrayList的内存效率非常低。如果在64位JVM上运行,从使用TIntArrayList可能会将内存使用量减少3倍甚至更多。

我怀疑递归是问题所在,想想最大递归深度是多少。该算法可以通过在树集合中收集ss中每个字符的索引,然后在需要在字符串中前进时简单地获取.tailSet来有效地实现

import java.util.*;


public class Test {

    public static Set<List<Integer>> solutions(List<TreeSet<Integer>> is, int n) {

        TreeSet<Integer> ts = is.get(0);
        Set<List<Integer>> sol = new HashSet<List<Integer>>();
        for (int i : ts.tailSet(n+1)) {
            if (is.size() == 1) {
                List<Integer> l = new ArrayList<Integer>();
                l.add(i);
                sol.add(l);
            } else 
                for (List<Integer> tail : solutions(is.subList(1, is.size()), i)) {
                    List<Integer> l = new ArrayList<Integer>();
                    l.add(i);
                    l.addAll(tail);
                    sol.add(l);
                }
        }
        return sol;
    }


    public static void main(String[] args) {
        String ss = "aaba";
        String s = "aa";

        List<TreeSet<Integer>> is = new ArrayList<TreeSet<Integer>>();

        // Compute all indecies of each character.
        for (int i = 0; i < s.length(); i++) {
            TreeSet<Integer> indecies = new TreeSet<Integer>();
            char c = s.charAt(i);
            for (int j = 0; j < ss.length(); j++) {
                if (ss.charAt(j) == c)
                    indecies.add(j);
            }
            is.add(indecies);
        }

        System.out.println(solutions(is, -1));
    }
}

为什么示例[0,1]、[0,3]和[1,3]的解决方案是?@aioobe-他的意思是他想要每一组常用字符之间的距离。因此,如果我们通过数组索引来标记每个字符,那么在位置0、1和3处都有a,所以解决方案集就是a的组合集。
[[0, 1], [1, 3], [0, 3]]