增加堆栈大小被认为是一种不好的做法吗?

时间:2015-10-24 02:00:10

标签: java stack-overflow depth-first-search

我在Java程序中得到了StackOverflowException,因此我使用-Xss100m增加了堆栈大小。这是否意味着我的代码有问题?我需要解决以下任务:

  1. 你有n件衣服
  2. 对于每一件衣服x,y,你知道x是否与y
  3. 相符
  4. 把所有的衣服放在最大量的衣柜里,但是你必须确保当你从每个衣柜里拿到1件衣服时它看起来不错(所以每件东西看起来都很合适)
  5. 我将它实现为一个图形,其中顶点是衣服,当它们看起来彼此不正确时,两个顶点之间有一条边。所以基本上我需要把每个连接顶点的“组”放到一个衣柜里。要做到这一点,我使用简单的DFS:

    SimpleGraph类的一部分

        Map<Integer, List<Integer>> edges;
    
        /**
         * Recursive implementation of DFS algorithm adjusted to SimpleGraph class
         * 
         * @param vertice               id of vertice we start at
         * @param visited               array holding info if given vertice was visited or not
         * @param applyToEachVertice    function applied to each vertice we visit
         * @return                      did we marked ANY vertice as visited ( if we DFS starting at
         *                               visited vertice it returns false and true otherwise )
         */
        boolean deepFirstSearch( int vertice, boolean[] visited, Consumer<Integer> applyToEachVertice )
        {
            if(visited[vertice])
               return false;
            visited[vertice] = true;
            applyToEachVertice.accept(vertice);
    
            // checks if vertice has any neighbours
            if(!edges.containsKey(vertice))
                return true;
    
            for( int v : edges.get(vertice) )
                if(!visited[v]) 
                    deepFirstSearch(v, visited, applyToEachVertice);
            return true;
        }
    

    主循环

        void resolve( SimpleGraph sg )
        {
            boolean[] visited = new boolean[sg.getVertNumber()];
            final int[] wardrobe = new int[sg.getVertNumber()];        
            for(int i = 0, warNr = 0; i < sg.getVertNumber(); i++)
            {
                final int cNr = warNr;
                if(sg.deepFirstSearch(i, visited, x -> wardrobe[x] = cNr))
                    warNr++;
            }
        }
    

    编辑:实际上以迭代方式实现DFS解决了这个问题。这意味着我可以在不改变堆栈大小的情况下运行我的应用程序。

    boolean deepFirstSearchNotRecursive( int vertice, boolean[] visited, Consumer<Integer> applyToEachVertice )
    {
        if(visited[vertice])
            return false;
    
        Deque<Integer> stack = new ArrayDeque<>();  
        stack.push(vertice);
    
        while(!stack.isEmpty())
        {
            Integer next = stack.pop();
            visited[next] = true;
            applyToEachVertice.accept(next);
            if(!edges.containsKey(next))
                continue;
            for(Integer i : edges.get(next))
                if(!visited[i])
                    stack.push(i);
        }
    
        return true;
    }
    

1 个答案:

答案 0 :(得分:1)

我认为你的问题不是由无限递归引起的,因为你可以从StackOverflowException堆栈跟踪中发现问题并且扩展堆栈大小对你没有帮助。

虽然有正当理由增加堆栈跟踪大小,但我敢说您的调用链的深度与传递给应用程序的输入大小成正比。在这种情况下,您永远不能将其配置得足够大(如果您不限制 size o输入,这对于图形来说可能是一个棘手的事情)。切换到递归深度与输入数据无关的算法是可行的方法。

当然,如果您有预定义的数据集或编写一个永远不会重复使用的丢弃脚本,那么切角应该重新实现算法的中心。