首页 > 解决方案 > 在 JAVA 中使用 recursion 获得不同的结果 StringBuilder 与 String

问题描述

当我以 StringBuilder 作为参数运行下面的代码时,我得到不同的输出:

public static List<String> generateParenthesis(int n) {
        if(n==0)
            return new ArrayList<String>();
        List<String> list = new ArrayList<>();
        generate(list, new StringBuilder(), 0, 0, n);
        return list;
    }
    public static void generate(List<String> list, StringBuilder s, int j, int k, int n)
    {
        if(s.length()>2*n || j>n || k>n || k>j)
            return;
        if(s.length()==2*n && j==n && k==n)
        {
            list.add(s.toString());
            return;
        }
        if(j<n)
        {
            generate(list, s.append("("), j+1, k, n);
        }
        if(k<j)
        {
            generate(list, s.append(")"), j, k+1, n);
        }
    }   

输出: [((()))]

当我使用参数作为字符串运行相同的代码时,我得到不同的输出:

        if(n==0)
            return new ArrayList<String>();
        List<String> list = new ArrayList<>();
        generate(list, "", 0, 0, n);
        return list;
    }
    public static void generate(List<String> list, String s, int j, int k, int n)
    {
        if(s.length()>2*n || j>n || k>n || k>j)
            return;
        if(s.length()==2*n && j==n && k==n)
        {
            list.add(s.toString());
            return;
        }
        if(j<n)
        {
            generate(list, s+"(", j+1, k, n);
        }
        if(k<j)
        {
            generate(list, s+")", j, k+1, n);
        }
    } 

输出: [((())), (()()), (())(), ()(()), ()()()]

谁能帮我理解为什么会这样?谢谢!!

标签: javastringrecursionstringbuilder

解决方案


不同之处在于它String是不可变的:每当您连接或以其他方式操作一个String对象时,您实际上是在创建一个String具有新值的新对象。

StringBuilder然而是可变的:您可以更改任何给定StringBuilder实例的值(这基本上是它存在的主要原因)。

所以在这一行:

generate(list, s.append("("), j+1, k, n);

  1. 修改StringBuilder实例
  2. 称呼generate
  3. StringBuilder通话后仍有修改

但在

generate(list, s+"(", j+1, k, n);

你改为

  1. 创造 String价值
  2. 调用generate,传递新值
  3. 调用后仍然s引用以前的值generate

推荐阅读