【问题标题】:Recursive Substrings out of bounds error递归子串越界错误
【发布时间】:2015-01-01 04:52:04
【问题描述】:

我必须创建一个递归方法来在字母“A”或“a”之前显示给定字符串的所有子字符串,并在此过程中忽略该字母。终止条件工作正常。但是,在继续条件下,我抛出了 indexoutofbounds 错误,我不完全确定为什么。据我所知,我在索引达到字符串长度之前停止循环。但我会在这里发布,以防我错过了什么。

class Tree
{
    void subStrings(String s)
    {
        if(s.length() == 1)
        {
            if(s.charAt(0) == 'A' || s.charAt(0) == 'a')
            {
                System.out.println("Cannot shorten substring.");
            }
            else
            {
                System.out.println(s);
            }

        }

        else
        {
            String subString = "";
            int i = 0;
            while(s.charAt(i) != 'A' && i < s.length())//bad line
            {   
                subString += s.charAt(i);
                i++;
            }

            if(subString.equals(""))
                subStrings(s.substring(i));
            else
            {
                System.out.println(subString);
                subStrings(s.substring(i));
            }
        }
    }

    int treeHeight(String tree)
    {
        return 0;
    }
}

【问题讨论】:

  • 所以您只是使用Aa 作为分隔符来拆分字符串?

标签: java recursion substring


【解决方案1】:

你需要颠倒这两个条件:

while(s.charAt(i) != 'A' && i < s.length()) { /*...*/ }

所以,应该是:

while(i < s.length() && s.charAt(i) != 'A') { /*...*/ }

否则,当字符串为空并尝试访问第一个字符(位置 0)时,您会得到越界异常。


如果您只是想split 使用aA 作为分隔符的字符串,您不妨这样做:

String[] substrings = str.split("[aA]");

如果绝对必须使用递归方法来实现,而不是逐个字符地处理字符串,您可以使用indexOf 来查找下一个aA 的位置。它可能看起来像这样:

public static void subStrings(String s) {
    int i = s.toLowerCase().indexOf('a');

    if (i >= 0) {
        System.out.println(s.substring(0, i));

        if (i + 1 < s.length()) {
            subStrings(s.substring(i + 1));
        }
    }
}

【讨论】:

  • 我编辑了循环以获得 indexOf 语句,但现在我抛出了 StackOverflow 错误。以前从未处理过此错误,所以我不确定发生了什么。
  • StackOverflowError 意味着(几乎在所有情况下)无限递归。您的终止工作不正常。
【解决方案2】:

由于其他一些问题,即使是 Robby 的重构也无法将您带到您无法到达的地方。对于您的异常,您必须迭代到i &lt; s.length() - 1,因为您正在增加循环中的索引,并且您在循环中使用的 charAt 方法从索引 0 开始。

进一步检查,您应该将 substring(i) 更改为 subStrings(s.substring(0, i)) 否则您将在递归中得到相同的字符串。以下应该适合你

    void subStrings(String s)
    {
        if(s == null || s.length() == 0 || s.charAt(0) == 'A' || s.charAt(0) == 'a')
        {
            System.out.println("Cannot shorten substring.");
            return;
        }
        if(s.length() != 1)
        {
            String subString = "";
            int i = 0;
            while(s.charAt(i) != 'A' && s.charAt(i) != 'a' && i < s.length() - 1)//bad line
            {
                subString += s.charAt(i);
                i++;
            }


            if(subString.equals(""))
                subStrings(s.substring(i));
            else
            {
                System.out.println(subString);
                subStrings(s.substring(0, i));
            }
        }
    }

【讨论】:

  • 从现在设置终止的方式来看,程序不会抓取任何通过遇到的第一个 'A' 或 'a' 的东西。
  • 在修改了一些东西之后,我发现将终止条件设置为 s.length()
猜你喜欢
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
  • 2011-12-13
  • 2016-04-12
  • 2017-09-23
  • 1970-01-01
  • 2023-03-14
  • 2014-06-06
相关资源
最近更新 更多