Java子串超出界限错误:解决方案?

时间:2015-10-28 01:33:46

标签: java

我的简介课程的这个实验要求我们返回猪拉丁语中的任何用户输入。 当我运行它并在控制台中键入任何字符串时,我似乎不断得到的错误是:

   java.lang.StringIndexOutOfBoundsException: String index out of range: -1

错误可在此处找到:

 thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);

我从另一篇文章中了解到这是问题所在:

  

IndexOutOfBoundsException - 如果beginIndex为负数,或者endIndex> gt;大于此String对象的长度,或者beginIndex大于> endIndex。

     

实际上,您的子字符串函数的右边缘可能低于左边的> 1。例如,当i =(size-1)且j = size时,您将计算> substring(size-1,1)。这是你错误的原因。 (通过Bes0ul回答)

我的问题是,这个问题的解决方案是什么?

以下是我使用的方法:

public String pigLatin(String x)
{
    String thisWord = "";
    x += " ";
    int indexOfNextNonLetter = 0, indexOfCurrentNonLetter = 0;
    for(int i = 0; i < x.length(); i++)
    {
        System.out.println("At least the loop works"); //Let's play a game called find the issue
        if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122) //if it isn't a letter
        {
            phrase += x.charAt(i); // add our non character to the new string
            for(int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
            {
                if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)
                {
                    indexOfNextNonLetter = j + i;
                    if(j+i > x.length())
                    System.out.print("Problem Here");
                    indexOfCurrentNonLetter = i;
                    System.out.println("noncharacter detected"); //I hope you found the issue
                    j = x.length();
                    thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);//between every pair of nonletters exists a word
                }
            }
            phrase += latinWord(thisWord); // translate the word
            i = indexOfNextNonLetter - 1;
        }
    }
    return phrase;
}

/*
 * This converts the passed word to pig latin
 */
public String latinWord(String word)
{
    String lWord = "";
    String beforeVowel = "";
    String afterVowel = "";
    boolean caps = false;
    char first = word.charAt(0);
    if(first > 'A' && first < 'Z')
    {
        first = Character.toLowerCase(first); //If the first char is capital, we need to account for this
        caps = true;
    }
    if(containsNoVowels(word))
        lWord = Character.toUpperCase(first) + word.substring(1) + "ay"; //If we have no vowels
    if(word.charAt(0) == 'A' || word.charAt(0) == 'a' || word.charAt(0) == 'E' || word.charAt(0) == 'e' || word.charAt(0) == 'I' || word.charAt(0) == '0'
    || word.charAt(0) == 'O' || word.charAt(0) == 'O' || word.charAt(0) == 'o' || word.charAt(0) == 'U' || word.charAt(0) == 'u')
    {
        lWord = Character.toUpperCase(first) + word.substring(1) + "yay"; //If the first char is a vowel
    }
    if(word.charAt(0) != 'A' || word.charAt(0) != 'a' || word.charAt(0) != 'E' || word.charAt(0) != 'e' || word.charAt(0) != 'I' || word.charAt(0) != '0'
    || word.charAt(0) != 'O' || word.charAt(0) != 'O' || word.charAt(0) != 'o' || word.charAt(0) != 'U' || word.charAt(0) != 'u')
    { //If the first letter isnt a vowel but we do have a vowel in the word
        for(int m = 0; m < word.length(); m++)//if we have a vowel in the word but it doesn't start with a vowel
        {
            if(word.charAt(m) == 'A' || word.charAt(m) == 'a' || word.charAt(m) == 'E' || word.charAt(m) == 'e' || word.charAt(m) == 'I' || word.charAt(m) == 'm'
            || word.charAt(m) == 'O' || word.charAt(m) == 'O' || word.charAt(m) == 'o' || word.charAt(m) == 'U' || word.charAt(m) == 'u')
            {                    
                for(int l = 0; l < word.substring(m).length(); l++)
                {
                    afterVowel += word.substring(m).charAt(l); //Build the part after the first vowel
                }
                m += word.length();
            }
            else
                beforeVowel += word.charAt(m);
        }
        if(caps == false)
            lWord = afterVowel + beforeVowel + "ay";
        else
        {
            first = Character.toUpperCase(afterVowel.charAt(0));
        }
    }

    return lWord;
}

/*
 * This function checks the string letter by letter to see if any of the letters are vowels.If there are none it returns true
 */
public boolean containsNoVowels(String wrd)
{
    for(int h = 0; h < wrd.length(); h++)
    {
        if(wrd.charAt(h) == 'A' || wrd.charAt(h) == 'a' || wrd.charAt(h) == 'E' || wrd.charAt(h) == 'e' || wrd.charAt(h) == 'I' || wrd.charAt(h) == 'h'
        || wrd.charAt(h) == 'O' || wrd.charAt(h) == 'O' || wrd.charAt(h) == 'o' || wrd.charAt(h) == 'U' || wrd.charAt(h) == 'u')
            return false;
        else
            return true;
    }
    return false;
}

1 个答案:

答案 0 :(得分:1)

我认为错误在于for中的第二个pigLatin()循环:

for (int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
{
     if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)

上面显示的最后一行开始检查char i。这是您在外循环中检查的相同char。所以测试会成功。而且我认为逻辑在这次迭代或后续迭代中都会崩溃。

我认为你想要的是:

for(int j = 1; j < x.substring(i).length(); j++)
{
     if (x.charAt(j) < 65 || x.charAt(j) > 90 && x.charAt(j) < 97 || x.charAt(j) > 122)

注意,有两处变化:

  1. j初始化1以测试for声明中的下一个字符
  2. j声明中测试i个字符,而不是if