【问题标题】:recursively add to strings in java递归地添加到java中的字符串
【发布时间】:2013-05-27 22:08:44
【问题描述】:

我正在尝试在 java 中将 int 123 转换为 String "CBA"

我知道我在递归中有一些误解

经过多次 println 语句,我知道在某一点上

ss 将成为“CBA”

但它会返回“CB”和“C”

我知道递归会这样工作,但我不知道如何解决它

谁能帮我写代码,谢谢!

public String recur ( int x, String ss )
{
    if ( x >= 1 && x < 10 )
        ss = ss + "A";

    if ( x >= 10 && x < 100 )
    {
        ss = ss + "B";
        recur( x % 10, ss);
    }

    if ( x >= 100 && x < 1000 )
    {
        ss = ss + "C";
        recur( x % 100, ss);    
    }
return ss;          

【问题讨论】:

  • 尽管 Java 允许这样做,但重用方法参数值是不好的做法。提示:使用StringBuilder
  • 请注意,虽然@fge 的评论是正确的,但它无助于解决 OP 的问题。 “提示”也是非常值得怀疑的。充其量只是边际微优化。如果 OP 关心性能,那么正确的优化将是迭代地实现它......
  • @StephenC 我不会将保证数据安全的东西称为“微优化”
  • @fge - 使用 StringBuilder 如何“保证数据安全”?无论如何,您所说的“数据安全”是什么?这里的问题是代码的正确性、健壮性和可读性,而不是“数据安全”。
  • @StephenC 很简单:对 stringbuilder 的任何优化都会影响 stringbuilder 本身;因此,您可以递归并将其作为参数传递,然后将sb.toString() 作为参数返回。这与不可变的String 不同。

标签: java string recursion


【解决方案1】:

您的方法不正确,对于初学者,您甚至不需要将字符串作为参数传递 - 只需在返回值中构建字符串即可。此外,从整数转换为字符串的逻辑过于复杂,只有在整数包含数字 1, 2, 3 时才有效!这是一种更简单的工作方法,它依次处理每个字符并适用于任何数字的整数:

public String recur(int x) {
    if (x <= 0)
        return "";
    return (char) (x % 10 + 'A' - 1) + recur(x / 10);
}

解释:

  • 基本情况发生在整数等于或小于零时,在这种情况下我们必须返回一个空字符串
  • 递归步骤的工作方式如下:
    • 我们通过取余数从整数中获取当前数字:x % 10,然后通过添加 'A' 和减去 1 将数字转换为大写字符
    • 我们将前一个结果与推进递归的结果连接起来,将整数除以10

【讨论】:

    【解决方案2】:

    (这个答案主要是针对花生画廊的......)

    这是我对上述问题的“最佳”递归解决方案的看法:

    public String recur ( int x )
    {
        if ( x >= 1 && x < 10 ) {
            return "A";
        } else if ( x >= 10 && x < 100 ) {
            return "B" + recur( x );
        } else if ( x >= 100 && x < 1000 ) {
            return "C" + recur( x );    
        } else {
            throw new IllegalArgumentException();
        }
    }
    
    System.err.println(recur(123));
    

    或更笼统地说:

    public String recur ( int x)
        return recur0( x, 0 );
    }
    
    public String recur0 ( int x, int i )
    {
        if ( x <= 0 ) {
            return "";
        else {
            return recur0( x % 10, i + 1 ) + ((char) ('A' + i));
        } 
    }
    
    System.err.println(recur(123));
    

    如您所见,不需要 StringBuilder。充其量, StringBuilder 是一种微优化。它不会使代码更安全或更具可读性。为了说明,这是使用 StringBuilder 重做的第一个版本

    public void recur ( int x, StringBuilder sb )
    {
        if ( x >= 1 && x < 10 ) {
            sb.append("A");
        } else if ( x >= 10 && x < 100 ) {
            sb.append("B");
            recur( x, sb );
        } else if ( x >= 100 && x < 1000 ) {
            sb.append("C");
            recur( x, sb );    
        } 
    }
    
    StringBuilder sb = new StringBuilder();
    recur(123, sb);
    System.err.println(sb.toString());
    

    但最初所说的问题的最简单解决方案是:

    public String nonRecur(int x) {
        if ( x >= 1 && x < 10 ) {
            return "A";
        } else if ( x >= 10 && x < 100 ) {
            return "BA";
        } else if ( x >= 100 && x < 1000 ) {
            return "CBA";    
        } else {
            throw new IllegalArgumentException();
        }
    }
    
    System.err.println(nonRecur(123));
    

    请注意,问题的表述方式存在相当大的歧义,@ÓscarLópez 的解决方案基于对问题的不同解释。他将数字的数字映射到字母,而不是用字母来表示大小。

    事实上,OP 的实际问题都不是这些解释,我认为任何答案都不会真正帮助他......即使他们确实回答了他的问题。

    【讨论】:

      【解决方案3】:

      您忽略了 recur 的返回值,因此在输出中只能看到第一级递归。

      因此您可以这样做以考虑返回值。 (只需将recur的输出分配给ss)

      ss = recur( x % 10, ss);
      

      和另一个电话。

      ss = recur( x % 100, ss);
      

      【讨论】:

      • 谢谢,对,我想我忽略了一些我已经改变的东西 recur(x % 10, ss);到 ss = recur(x % 10, ss); ...但我仍然在输出中只得到 C
      • 您是否为您的两次重复通话都这样做了?我认为不是
      • @user2442300 如果回答对您有帮助,可以accept the answer
      • OP 的解决方案仅在整数包含数字 1、2 或 3 时才有效 - 它不够通用,并且对于包含不同数字的任何数字都会失败
      • @ÓscarLópez - 我想我们都在猜测实际的问题陈述到底是什么。当然,您无法从单个示例中推断出它......以及解决它的失败尝试
      猜你喜欢
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2012-05-27
      • 2014-02-27
      • 2020-03-15
      相关资源
      最近更新 更多