Java 在递归中何时在数组上使用ArrayList

Java 在递归中何时在数组上使用ArrayList,java,arrays,recursion,arraylist,Java,Arrays,Recursion,Arraylist,所以我有这个问题。我试图编写一个程序来打印所有有效的括号排列,即对于3个括号,我们可以有((()),(()),()(),(())等等 我有一个工作代码 public static void main(String[] args) { int number = 3; // No. of brackets int cn = number; int on = number; // open and closed brackets respectively cha

所以我有这个问题。我试图编写一个程序来打印所有有效的括号排列,即对于3个括号,我们可以有((()),(()),()(),(())等等

我有一个工作代码

public static void main(String[] args) {
    int number = 3; // No. of brackets
    int cn = number;
    int on = number;
    // open and closed brackets respectively
    char[] sol = new char[6];
    printSol(on, cn, sol, 0);
}

public static void printSol(int cn, int on, char[] sol, int k) {
    if (on == 0 && cn == 0) {
        System.out.println("");
        for (int i = 0; i < 6; i++) {
            System.out.print(sol[i]);
        }
    }

    else {
        if (on > 0) {
            if (cn > 0) {
                sol[k] = '(';
                printSol(on - 1, cn, sol, k + 1);
            }
        }

        if (cn > on) {
            sol[k] = ')';
            printSol(on, cn - 1, sol, k + 1);
        }
    }
}
publicstaticvoidmain(字符串[]args){
int number=3;//括号的数量
int cn=数字;
int on=数字;
//分别为开括号和闭括号
char[]sol=新字符[6];
printSol(on,cn,sol,0);
}
公共静态void printSol(int-cn,int-on,char[]sol,int-k){
如果(on==0&&cn==0){
System.out.println(“”);
对于(int i=0;i<6;i++){
系统输出打印(sol[i]);
}
}
否则{
如果(打开>0){
如果(cn>0){
sol[k]='(';
printSol(on-1,cn,sol,k+1);
}
}
如果(cn>on){
sol[k]=')';
printSol(on,cn-1,sol,k+1);
}
}
}
现在的问题是,我想使用ArrayList而不是char array来实现这一点。 我试过了,但还是出错了。如果有人有任何建议,请告诉我。问这个问题的主要目的是想知道在递归问题中,什么时候我更喜欢数组列表而不是数组

附言。 我很抱歉缩进不好,因为我不得不键入整个程序由于冲浪的限制,也可能是一些语法错误,但我尽力了。 谢谢
Mohit

您希望避免在递归时按值传递大型数据结构,因为它会消耗大量内存。总的来说,这是我能想到的唯一一件事。将引用传递给数组或ArrayList是可以的。总的来说,我更喜欢ArrayList


查看Java的
堆栈
类,特别是这个问题。

我认为您使用
char[]
做得很好。这很快,也很中肯

我想说,在实践中遇到的大多数递归问题都不遵循这种模式。这是因为通常在需要递归的问题中,您在搜索树上搜索一个特定目标(树上的一个特定叶节点)。您正在执行迭代:您正在尝试访问树上的每个叶节点,并为每个叶节点执行一个操作

使用常见的搜索算法(如深度优先搜索),您不需要在递归时准备结果,而是在找到目标后放松时准备结果

但是,对于这样做的情况,
char[]
非常有效。您基本上是通过参数
sol
k
模拟堆栈(sol在k指向堆栈顶部时保存数据)。正如其他人所注意到的,您可以直接使用堆栈(通过传递
Deque
实现,通常是
LinkedList

在我看来,
ArrayList
是一种倒退。如果要使用集合,请使用针对该问题而设计的集合

编辑:这里有一个未经测试的实现,它使用了一个Deque:

public static void printSol(int cn, int on, Deque<Character> sol) {
    if (on == 0 && cn == 0) {
        System.out.println("");
        for ( Iterator<Character> it = sol.descendingIterator(); it.hasNext(); ) {
            System.out.println(it.next());
        }
    }

    else {
        if (on > 0) {
            if (cn > 0) {
                sol.push('(');
                printSol(on - 1, cn, sol);
                sol.pop();
            }
        }

        if (cn > on) {
            sol.push(')');
            printSol(on, cn - 1, sol);
            sol.pop();
        }
    }
}

//...
printSol(3, 3, new ArrayDeque<Character>(6));
我意识到没有人(包括我自己)真正回答了你的问题。我想你已经确信在这里使用
ArrayList
是不可取的。但是你怎么能让它工作呢

最简单的方法是基本上用它来伪造堆栈:

public static void printSol(int cn, int on, ArrayList<Character> sol) {
   //...
   sol.add('(');
   printSol(on - 1, cn, sol);
   sol.remove(sol.size() - 1);
publicstaticvoidprintsol(int-cn,int-on,ArrayList-sol){
//...
加入"(""");;
printSol(on-1,cn,sol);
sol.remove(sol.size()-1);

谢谢你为我缩进了它。当你尝试ArrayList时,你遇到了什么错误?知道这一点会让你更容易找到问题。请确切地说明你遇到了什么错误-编译、运行时、测试失败或…?一般来说,你的问题越详细、越精确,你得到的帮助就越好…好的,错误是我获取错误的解决方案。使用ArrayList重新编写代码将花费大量时间。与数组不同,ArrayList会越来越长。我的递归步骤是调用printSol(cn,on,sol)在sol是ArrayList sol的每一步中,Tony我都不想使用任何API,也不想获得低级知识。有人能帮助我使用ArrayList解决这个问题吗?+1,堆栈是正确的数据结构。但我不会使用
堆栈
,这太可怕了,是公认的bigtime库设计缺陷,应该慢慢死掉。我会告诉我们的e a
Deque
(具体类型
LinkedList
)。您的问题似乎不仅仅是数组与arrayList;-)@unhillbilly:1)正如您所说,它是同步的。2)它使用继承而不是组合,这意味着您不能将其视为“堆栈”:它总是将Vector的方法作为行李随身携带,这意味着人们可以对它做一些你不应该对堆栈做的事情。相关的,3)“堆栈”应该是一个接口的名称,这样你至少可以有一个仅用于堆栈操作的接口(类似于Queue和Deque)4)虽然它并没有被正式删除,但是JavaDoc称不使用它,而是使用<代码> Deque <代码>。谢谢你的回复。在上下文中,让我们来解决一个问题,我需要在树中找到所有可能的路径(从根到叶子)。。这是一个类似于我发布的一个递归问题,我想使用数组并将其用作堆栈。我在接受char[]方面没有问题作为解决方案,但问题是我无法理解何时在递归中使用ArrayList。我对java是新手。@Pelooo:我想说ArrayList在递归中几乎没有什么用处。从来没有。在本例中绝对没有。大多数情况下,你是在“构建路径”对于叶节点,您需要一个堆栈。堆栈有两种主要的实现方式:一种是链表,其中只包含头节点;另一种是数组,其中保存指向堆栈顶部的指针。如果您希望在不使用类的情况下实现它,那么这两种实现方式都很好。但是,如果您希望使用集合类,则这两种实现方式
public static void printSol(int cn, int on, ArrayList<Character> sol) {
   //...
   sol.add('(');
   printSol(on - 1, cn, sol);
   sol.remove(sol.size() - 1);