递归子串超出界限错误

时间:2014-11-05 04:30:40

标签: java recursion substring

我必须创建一个递归方法来显示给定字符串的所有子串之前的字母' 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;
    }
}

2 个答案:

答案 0 :(得分:1)

即使是罗比的重构也不会让你因为其他一些问题而获胜。对于您的异常,您必须迭代到i < 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));
            }
        }
    }

答案 1 :(得分:0)

你需要扭转这两个条件:

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));
        }
    }
}