Jump to content

Java StringIndexOutOfBoundsException help

- - - - -

  • Please log in to reply
12 replies to this topic

#1
zzuum

zzuum

    Newbie

  • Members
  • Pip
  • 5 posts
Hello, I'm trying to make a class that will take a given string and convert it to pig latin. Basically, words without vowels add a -ay to the end, words starting with a vowel add -yay to the end, and words with a vowel somewhere in the middle are split at the vowel so the vowel comes first, everything before the vowel goes to the end of the word, and -ay goes to the end.

I created some methods to try to do this. The first was a method to determine if the first letter was a vowel and return true if it was and false if not. here is the code:

	private boolean isVowel(char let)

	{

		if(let == 'e' || let == 'a' || let == 'i' || let == 'o' || let == 'u' || let == 'A' || let == 'E' || let == 'I' || let == 'O' || let == 'U' )

		{

			return true;

		}

		else

		{

			return false;

		}

	}

the second method determined what and how to add the letters at the end. If the word has a vowel in front, add -ay. If not, put the first letter to the back and see if it is the same word as the original. If it is, add -yay to the end. If not, recursively call itself to see if it has a vowel in front. Here is the code:

	private String fixWord(String word)

	{

		final String original = word;

		String endWord;

		String word2;

		if(isVowel(word.charAt(0)) == true)

		{

			endWord = word + "yay";

			return endWord;

		}

		else

		{	

			word2 = word.substring(1) + word.charAt(0);

			if(word2.equals(original) == true)

			{

				endWord = original + "ay";

				return endWord;

			}

			else

			{

				endWord = fixWord(word2);

				return endWord;

			}

		}

	}

The last method took a given sentence and transformed all the words to pig latin using fixWord. If the string is one word, it used fixWord on it and returned the result. If not, it used fixWord on the first word (as determined by str.indexOf(" ")) and sent the rest of the sentence back to splitWords method.
here is the code:

	public String splitWords(String str)

	{

		String word = str.substring(0,str.indexOf(" ") - 1);

		String otherWords = str.substring(str.indexOf(" ") + 1,str.length());

		String result;

		if (str.indexOf(" ") == str.length())

		{

			result = fixWord(word);

		}

		else

		{

			result = fixWord(word) + splitWords(otherWords);

		}

		return result;

	}

all of this was use in the pigLatin method, shown here:

	public String pigLatin(String str)

	{

		String result;

		clean(str);

		str = str.toLowerCase();

		str = str + " ";

		result = splitWords(str);

		return str;

	}
the clean method simply replaces all puncuation with blanks and trims the string.

So with all this, I used a seperate tester file to see if it works. I tested the string "Good people eat pizza" and got the following errors:


Process started >>>

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2

	at java.lang.String.substring(String.java:1937)

	at StringUtil.splitWords(StringUtil.java:76)

	at StringUtil.splitWords(StringUtil.java:85)

	at StringUtil.splitWords(StringUtil.java:85)

	at StringUtil.splitWords(StringUtil.java:85)

	at StringUtil.splitWords(StringUtil.java:85)

	at StringUtil.pigLatin(StringUtil.java:70)

	at StringTester.main(StringTester.java:21)

<<< Process finished.

what is wrong? This is really irritating to me becuase it took me a couple hours to conceive this code and it just won't work. Can anyone help with this problem and make suggestions?

note: i will attach java file and tester

Edited by Roger, 05 December 2010 - 08:37 AM.
added code tags


#2
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
You don't want to remove spaces in your clean method or you don't have words anymore.

Further i have added a space to the splitwords method.
And i rewrote the fixWord method.
 public String splitWords(String str) {
        String word = str.substring(0, str.indexOf(" "));
        String otherWords = str.substring(str.indexOf(" ") + 1, str.length());
        String result;
        if (str.indexOf(" ") == str.length() - 1) {
            result = fixWord(word);
        } else {
            result = fixWord(word)[COLOR="red"][B] + " "[/B][/COLOR] + splitWords(otherWords);
        }
        return result;
    }

    private String fixWord(String word) {
        if (isVowel(word.charAt(0))) {
            return word + "yay";
        }

        boolean hasVowel = false;
        for (int i = 0; i < word.length(); i++) {
            if (isVowel(word.charAt(i))) {
                hasVowel = true;
                break;
            }
        }

        if (!hasVowel) {
            return word + "ay";
        }

        String newWord = "";
        for (int i = 0; i < word.length(); i++) {
            if (isVowel(word.charAt(i))) {
                newWord = word.substring(i) + word.substring(0, i);
                break;
            }
        }

        return newWord += "ay";
    }

fixWord has 3 parts.
First it checks if the word starts with a vowel, if so return it with "yay" attached.
Then it goes trough the word to see if it has a vowel. If it doesn't have one. return word with "ay" attached.
And otherwise i do the piglatin stuff, putting all letters before the first vowel behind and attaching "ay".


In addition. The clean method should return the cleansed String:
private String clean(String str) {
        str = str.trim();
        str = str.replace(",", "");
        str = str.replace(".", "");
        str = str.replace(";", "");
        str = str.replace("!", "");
        str = str.replace("?", "");
        str = str.replace("'", "");
        str = str.replace("/", "");
        str = str.replace("\\", "");
        str = str.replace("|", "");
        str = str.replace(":", "");
        str = str.replace("\"", "");
        return str;        
    }
And upon using the clean method you must catch the string:
str = clean(str);


#3
zzuum

zzuum

    Newbie

  • Members
  • Pip
  • 5 posts
Thanks for the help oxano, but in reality I am in a programming class for this project and we have not learned "for" statements yet. The only thinks I am supposed to use for this assignment are Strings, String methods, if statements, and recursive calling ( on top of the basics). So if you could help me with the code you wrote and somehow rewrite the for statement into something I have learned to use, that would be much appreciated. Thanks!

#4
eafkuor

eafkuor

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 218 posts
you didn't do the for instruction but you did recursion?

#5
zzuum

zzuum

    Newbie

  • Members
  • Pip
  • 5 posts
Well for my project I'm not supposed to use any "for" statements, only recursion and/or if /else statements.

#6
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
What about while loops?

#7
twanbaten

twanbaten

    Newbie

  • Members
  • Pip
  • 6 posts
If I understand your problem correctly, you would want to return result in pagLatin(String str) not str.
public String pigLatin(String str)

{

String result;

clean(str);

str = str.toLowerCase();

str = str + " ";

result = splitWords(str);

return str;

}

As stated by oxano, the clean method should not clean spaces.
Also, in the following, 'word' is 1 character short. The substring already excludes the space.
String word = str.substring(0, str.indexOf(" "));

Then you want to get otherwords that needs at least 2 words, otherwise the last character would be the space and and str.indexOf(" ") + 1 would be out of bounds (Hence the error). This solves it:
if (str.indexOf(" ") == str.length() - 1) // last character is always 1 shorter than length

{

result = fixWord(word);

}

else

{

String otherWords = str.substring(str.indexOf(" ") + 1); // exclude first word an space

result = fixWord(word) + " " + splitWords(otherWords); // the space to seperate the words

}

return result;

}

Hope this is any help.

#8
zzuum

zzuum

    Newbie

  • Members
  • Pip
  • 5 posts
Ok, I got rid of the stringindexoutofboundsexception error, but now my code is not properly functioning when attempting to turn words without vowels into pig latin, such as "why." It overflows the stack and I cannot figure out why as my code seems very straight forward. It says the error is in the fixWord method:

private String fixWord(String word)
{
final String original = word;
String endWord;
String word2 = word.substring(1) + word.charAt(0);
if(word2.compareTo(original) == 1)
{
if(isVowel(word.charAt(0)) == true)
endWord = original + "yay";
else
endWord = original + "ay";
}
else
{
if(isVowel(word2.charAt(0)) == true)
endWord = word2 + "ay";
else
endWord = fixWord(word2);
}
return endWord;
}

and here is the error output:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:391)
at java.lang.StringBuilder.append(StringBuilder.java:119)
at StringUtil.fixWord(StringUtil.java:95)
at StringUtil.fixWord(StringUtil.java:109)
at StringUtil.fixWord(StringUtil.java:109)...
last line repeats until it just crashes.

Any ideas?

#9
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
There is a maximum amount of times you can recurse. Your sentence was too long.

#10
corecase

corecase

    Newbie

  • Members
  • Pip
  • 4 posts
First of all i wanted to point out that the substring method takes in TWO attributes not one. Basically it takes in a range.
"String word2 = word.substring(1) + word.charAt(0);" <-- this is incorrect because you only put ONE attribute in the parenthesis.

For example:
public static void main(String [] args)
{
    String test = "Hello";
    System.out.println(test.substring(0,2));
}

This code would print to the screen "He".
So i didn't really look at what you're trying to do with the substring there(in your code) but i'm pretty sure the way you're using it is wrong.
Hope this helps! I'll take a better look at it a bit later if it still doesn't work.

#11
zzuum

zzuum

    Newbie

  • Members
  • Pip
  • 5 posts
Actually you are wrong; substring with only 1 parameter outputs the character at the number and everything after it.

#12
Xylyze

Xylyze

    Newbie

  • Members
  • Pip
  • 8 posts
private Boolean isVowel(char letter)

{

	String vowelString = "eaiouAEIOU";

	if (vowelString.contains(Character.toString(letter)))

	{

		return true;

	}

	return false;

}

The OO way to do it ;)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users