【问题标题】:Finding all paths using recursive method使用递归方法查找所有路径
【发布时间】:2013-03-14 05:22:10
【问题描述】:

我想练习一个问题,但我无法弄清楚如何为其编写递归算法。我有一个布局如下的文件:

4
(())
()((
(()(
))))

这个问题来自 USACO。 http://www.usaco.org/index.php?page=viewproblem2&cpid=189

问题陈述复制粘贴如下:

虽然 Bessie the cow 找到了每一串平衡的括号 在美学上令人愉悦,她特别喜欢她的弦乐 调用“完美”平衡 - 由 ('s 后面的字符串组成 由一串具有相同长度的 ) 组成。例如:

(((())))

有一天,贝西在穿过谷仓时发现了一个 N x N 网格 地面上的马蹄铁,每个马蹄铁的方向是这样的 它看起来像(或)。从左上角开始 这个格子,贝西想四处走走捡马蹄铁 她拿起的琴弦非常平衡。 请帮助她 计算她能找到的最长完美平衡弦的长度 获得。

在每一步中,Bessie 都可以向上、向下、向左或向右移动。她只能 移动到包含马蹄铁的网格位置,当她这样做时 这个,她拿起马蹄铁,让她不能再往回走 到同一个位置(因为它现在没有马蹄铁)。她从 拿起网格左上角的马蹄铁。贝西 只捡起一系列马蹄铁,形成完美平衡 绳子,因此她可能无法拿起所有 网格中的马蹄铁。

我在试图弄清楚如何创建一个递归找到最佳路径的算法时遇到了问题。谁能指出我正确的方向,或者有任何我可以看的例子来获得一个想法?我一直在搜索,但我发现的所有示例都是从一个点到另一个点,并且没有找到矩阵/数组中的所有可能路径。

package bessiehorseshoe;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BessieHorseShoe {

    int answer = 0;
    int matrixSize = 0;

    public static void main(String[] args) throws IOException {
        BessieHorseShoe goBessieGo = new BessieHorseShoe();
    }

    BessieHorseShoe() throws IOException {
        int rowFilled = 0;
        int currentColumn = 0;
        int character = 0;

        BufferedReader inputFile = new BufferedReader(new FileReader("hshoe.in"));
        String inputLine = inputFile.readLine();
        matrixSize = Character.digit(inputLine.charAt(0), 10);
        System.out.println(matrixSize);

        char[][] pMatrix = new char[matrixSize][matrixSize];

        while ((character = inputFile.read()) != -1) {
            char c = (char) character;
            if (c == '(' || c == ')') {
                pMatrix[rowFilled][currentColumn] = c;
                System.out.print(pMatrix[rowFilled][currentColumn]);
                rowFilled++;
                if (rowFilled == matrixSize) {
                    currentColumn++;
                    rowFilled = 0;
                    System.out.println();
                }
            }
        }
        matchHorseShoes(pMatrix);
    }

    public int matchHorseShoes(char[][] pMatrix) {
        if (pMatrix[0][0] == ')') {
            System.out.println("Pattern starts with ')'. No possible path!");
            return 0;
        }
        System.out.println("Works");
        return 0;
    }
}

【问题讨论】:

    标签: java recursion


    【解决方案1】:

    以下算法将解决您的问题。您还可以使用 memoization 来加快运行时间。 这个想法很简单:

    • 在开括号时增加开括号的计数;
    • 如果用星号关闭,则必须继续关闭并增加右括号;
    • 如果您正在关闭并且右括号的数量大于或等于打开的括号的数量,请停止并返回此值。

    所有其余代码都是语法糖。 (从返回的访问项目列表中可以轻松获得您想要的输出)。

    import java.util.LinkedList;
    import java.util.List;
    
    public class USACO {
    
    static class Path {
    
        public List<String> items;
        public int value;
    
        public Path() {
            this.items = new LinkedList<String>();
            this.value = 0;
        }
    
    }
    
    public static void main(final String[] args) {
        final int n = 5;
        final String[][] input = new String[n][n];
        // Create a random input of size n
        for (int y = 0; y < n; y++) {
            for (int x = 0; x < n; x++) {
                input[y][x] = Math.random() < 0.5 ? "(" : ")";
                System.out.print(input[y][x] + " ");
            }
            System.out.println();
        }
        final Path bestPath = longestPath(n, input, 0, 0, 0, 0, input[0][0] == "(");
        System.out.println("Max:" + bestPath.value + "\n" + bestPath.items);
    }
    
    public static Path longestPath(final int n, final String[][] input, final int x, final int y, int numberOpened, int numberClosed,
            final boolean wasOpening) {
        if (input == null) {
            return new Path();
        } else if (!wasOpening && (numberClosed >= numberOpened)) { // Reached a solution
            final Path path = new Path();
            path.value = numberOpened;
            path.items.add("(" + x + "," + y + ")");
            return path;
        } else if ((x < 0) || (y < 0) || (x >= n) || (y >= n)) { // Out of bound
            return new Path();
        } else if (input[y][x] == "") { // Already visited this item
            return new Path();
        } else {
            final String parenthese = input[y][x];
            // Increment the number of consecutive opened or closed visited
            if (parenthese.equals("(")) {
                numberOpened++;
            } else {
                numberClosed++;
            }
            input[y][x] = ""; // Mark as visited
            Path bestPath = new Path();
            bestPath.value = Integer.MIN_VALUE;
            // Explore the other items
            for (int dy = -1; dy <= 1; dy++) {
                for (int dx = -1; dx <= 1; dx++) {
                    if (((dy == 0) || (dx == 0)) && (dy != dx)) { // go only up, down, left, right
                        final boolean opening = (parenthese == "(");
                        if (wasOpening || !opening) {
                            // Find the longest among all the near items
                            final Path possiblePath = longestPath(n, input, x + dx, y + dy, numberOpened, numberClosed, opening);
                            if (possiblePath.value > bestPath.value) {
                                bestPath = possiblePath;
                                bestPath.items.add("(" + x + "," + y + ")");
                            }
                        }
                    }
                }
            }
            input[y][x] = parenthese; // mark as not visited
            return bestPath;
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      • 2015-03-11
      • 2023-04-05
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      相关资源
      最近更新 更多