String index out of range - Why is this occurring? - java

(Please keep in mind I have only been studying java for under a month on my own)
I am trying to make a program that simply tells you the last char of the name you give the program. Here is my code:
import java.util.Scanner;
public class LastCharacter {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("hey");
String name = reader.nextLine();
lastChar(name);
}
public static char lastChar(String text) {
char lastChar = '\0';;
int i = 0;
for (i = 0; i <= text.length(); i++) {
lastChar = text.charAt(i);
}
System.out.println(lastChar);
return lastChar;
}
}
Error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:658)
at LastCharacter.lastChar(LastCharacter.java:19)
at LastCharacter.main(LastCharacter.java:11)
Java Result: 1
I also know this can be made by subtracting the length of the string by 1, however I would like to know why this method isn't working. I don't really know how to word this but do strings and chars not get along? (pls dont make fun of me)
Thanks!

Java strings start at a base index of 0. Therefore, this line: for (i = 0; i <= text.length(); i++) { is trying to access an index that doesn't exist. The string main only goes from 0 to 3. So, when you try to access index 4, you get the out of bounds error.
Replace this line:
for (i = 0; i <= text.length(); i++) {
With this:
for (i = 0; i < text.length(); i++) { to fix the problem.

The problem is because Java uses a 0 index array for the string. This means that your for loop i <= text.length() is going to the last character +1. In a name like "Joe"
J = 0,
o = 1,
e = 2
The length of "Joe" is 3 and therefor the loop goes to index(3) which is out of the bounds of the character array.

Two things to take note here:
1.) The length() method in Java String class returns the number of characters of a string
2.) Java arrays uses zero-base index
So, to accomplish your task of getting the last character of the name string :
public static char lastChar(String text) {
int textLength = text.length();
char lastChar = text.charAt(textLength - 1); //first char starts from index 0
return lastChar;
}
Hope it helps.

You are out of bounds! The condition should be:
i < text.length()
for (i = 0; i < text.length(); i++) {
lastChar = text.charAt(i);
}

Strings are 0 based, meaning the first index is 0. So for the string "mom", the 0th index is "m", the 1st index is "o" and the 2nd index is "m". That means this string doesn't have a third index, even though its length is 3! Based on that, your loop should be:
for (i = 0; i < text.length(); i++) {
lastChar = text.charAt(i);
}
However, there is an even better way to do it with no loops at all. We can simply get the character at the last index of the string without looping over each character. It is less complicated and more efficent:
lastChar = text.charAt(text.length() - 1);

Related

What is the difference between .length() and .length()-1 when trying to count substrings?

What is the difference between using .length() and .length()-1 to find how many times letters occur in a string?
example:
for (int i = 0; i < str.length(); i++)
{
if (str.substring(i, i + 1).equals("e"))
{
count++;
}
}
System.out.println(count);
vs
for (int i = 0; i < str.length() - 1; i++)
{
if (str.substring(i, i + 2).equals("th"))
{
count++;
}
}
System.out.println(count);
Why can't we just use str.length() for both?
Because in the second example, you take a substring of 2 characters instead of one, like in the first example. Thus, by having the for loop only run until length - 1, the last iteration in the loop takes the characters at index length - 1 and length from the string. If you would check against length in the for loop, the substring in the last iteration would take the characters at position length and length + 1, which obviously wouldn't work.
You can make a function that works for all substrings. It would look like:
int countSubstrings(String str, String s) {
int count = 0;
for (int i = 0; i < str.length() - s.length() + 1; i++)
{
if (str.substring(i, i + s.length()).equals(s))
{
count++;
}
}
return count;
}
You need to stop looping over the string earlier as the substring that you are checking becomes longer.
(Note: the above method can be implemented more efficiently - using String.regionMatches - but it's for illustrating you question)
Unfortunately, in this case:
count = 0;
for ( int i = 0; i < str.length(); i++) {
if (str.substring(i, i + 2).equals("th")) {
count++;
}
}
System.out.println(count);
You will get the following exception.
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 4, e
nd 6, length 5
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3756)
at java.base/java.lang.String.substring(String.java:1902)
at stackOverflow.Pattern.main(Pattern.java:22)
Because i+2 would check for the i+1 location of the string and that is beyond it's length.
If you were to use str.length() for the second one when it reaches the highest i value when it does a substring i+2 will go off the end of str

Would need a little bit of clarification

Can you guys, please, explain to me what does count[word.charAt(i)]++, exactly do in this code and overall--?
public static void main(String[] args) {
String S = "Some random text to test.";
int count[] = new int[124];
for (int i=0; i< S.length(); i++) {
count[S.charAt(i)]++;
System.out.print(count[S.charAt(i)] + " ");
}
int max = 1;
char result = ' ';
for (int i = 0; i < S.length(); i++) {
if (max < count[S.charAt(i)] && S.charAt(i) != ' ') {
max = count[S.charAt(i)];
result = S.charAt(i);
}
}
System.out.println(result);
}
The printing of count[S.charAt(i)] was just me trying to figure it out.
S.charAt(i) returns the character in the i-th position of that string S.
Then count[S.charAt(i)] will execute like this. Lets say you get 'S' as the character. Then the character value for 'S' will be 83. So, it will take the element of the 83 index in count array and increment it by one.
word.charAt(i) returns the character at the i-th index in the String word.
count is an int array with all zeros automatically : int count[] = new int[124];
count[i]++ increments the value that is in count at index i by 1.
Here, you're passing word.charAt(i) as an index i.e count[word.charAt(i)]++, and what it does is:
-Evaluate word.charAt(i) first, but
note that index i must be an integer!
so automatically gets the ASCII value of the character. For example ('a' = 97, 'b' = 98..)
-then, count[ASCII number returned]++, for example count[97]++, will be incremented and now count[97] = 1
But note that if your String has '}', there will be Index out of bound exception, since its ASCII value is 125; and 125 > 124 the size of count!

I am trying to insert a string character to another string. How can I achieve it in java?

This is the code I am working upon. I dont know where I am going wrong.
package mcdcpairwise;
import java.io.*;
import java.util.*;
public class Permutation
{
public static void main(String[] args)
{
String a="000";
String b="|&";
for (int i=0; i < a.length(); i++){
if (i % 2 != 0){
a = a.substring(0,i-1) + b.substring(0,i-1). + a.substring(i, a.length()) + b.substring(i, b.length());
System.out.println(a);
}
}
}
}
The error I am facing is:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -2 at
java.lang.String.substring(String.java:1967) at
mcdcpairwise.Permutation.main(Permutation.java:13)
The output should be :
0|0&0
It isn't clear from your question exactly what your "rules" are for processing this. However, your output seems to simply insert a character between each character of your source a string.
Instead of using a substring, create a separate StringBuilder to add individual characters to. The code below produces the output you are looking for:
String string = "000";
StringBuilder output = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
// Get current character in the string
char c = string.charAt(i);
// Add the current character to the output
output.append(c);
// If more characters exist, add the pipe
if (i != string.length() - 1) {
output.append("|");
}
}
System.out.println(output.toString());
The right code should be a.substring(0,i).
You can use String.toCharArray to get a char[] from a String. That way we can iterate more easily both String using an index.
String a="000";
String b="|&";
char[] arrayA = a.toCharArray();
char[] arrayB = b.toCharArray();
Then, all we have to do is to merge two array (from Strings) taking one character from both. Adding two conditions (one per array) to prevent any ArrayIndexOutOfBOundsException, we can insure we will merge two arrays.
StringBuilder sb = new StringBuilder();
//Add a char from both array (until we reach on of the limit)
int i = 0;
while( i < arrayA.length && i < arrayB.length){
sb.append(arrayA[i]).append(arrayB[i]);
++i;
}
Then we just need to add the remaining characters using a for loop on both arrays. Only one of those loop will be triggered (or none) since at least one previous condition (i < arrayA.length && i < arrayB.length) is already false.
//Add the rest of `a` if any
for(int j = i; j < arrayA.length; ++j){
sb.append(arrayA[j]);
}
//Add the rest of `b` if any
for(int j = i; j < arrayB.length; ++j){
sb.append(arrayB[j]);
}
System.out.println(sb.toString());
0|0&0
Here’s a one line solution:
System.out.println((a + b).replaceAll("(?<=.)(?=.{" + (a.length() - 1) + "}(.))|.(?=.{0," + (b.length() - 1) + "}$)", "$1"));
This works with all combinations of non-blank starting strings.
See live demo.

Find all substrings of a string - StringIndexOutOfBoundsException

I created class Word. Word has a constructor that takes a string argument and one method getSubstrings which returns a String containing all substring of word, sorted by length.
For example, if the user provides the input "rum", the method returns a
string that will print like this:
r
u
m
ru
um
rum
I want to concatenate the substrings in a String, separating them with a newline ("\n"). Then return the string.
Code:
public class Word {
String word;
public Word(String word) {
this.word = word;
}
/**
* Gets all the substrings of this Word.
* #return all substrings of this Word separated by newline
*/
public String getSubstrings()
{
String str = "";
int i, j;
for (i = 0; i < word.length(); i++) {
for (j = 0; j < word.length(); j++) {
str = word.substring(i, i + j);
str += "\n";
}
}
return str;
}
But it throws exception:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1911)
I stuck at this point. Maybe, you have other suggestions according this method signature public String getSubstrings().
How to solve this issue?
Analysis of Exception:
From Java7 Docs of StringIndexOutOfBoundsException
public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException
Thrown by String methods to indicate that an index is either negative or greater than the size of the string.
From Java 7 Docs of substring
public String substring(int beginIndex,int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
I guess this: length of the substring is endIndex-beginIndex comes into String index out of range: -1. I have tested with multiple cases holding my assumption true but appreciate any other proof.
For -1: "rum".substring(2,1); will give you String index out of range: -1
Parameters:
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
Cause of StringIndexOutOfBoundsException:
In the given code snippet, substring is trying to fetch string which has endIndex more than the total length of String (i+j will exceed the total length of string):
str = word.substring(i, i + j);
Consider the case when i=2 and j=2 for word "rum"
then str=word.substring(2, 4);
would not be possible
Solution similar to code snippet given in Question:
This should solve the problem:
public String getSubstrings()
{
String str="",substr = "";
for (int i = 0; i < word.length(); i++) {
for (int j = 0; i+j <= word.length(); j++) { //added i+j and equal to comparison
substr = word.substring(j, i + j); //changed word.substring(i, i + j) to word.substring(j, i + j)
if("".equals(substr))continue; //removing empty substrings
str += substr; //added concatenation + operation
str += "\n";
}
}
return str+word;
}
Test Case:
For word="rum", this will give output:
r
u
m
ru
um
rum
Your logic seems convoluted , the source of exception:
str = word.substring(i, i + j);
Consider your i and j both equals word.length()-1 , then the substring() will fail.
You can simply do :
public String getSubstrings(String word){
StringBuilder sub= new StringBuilder();
for( int i = 0 ; i < word.length() ; i++ )
{
for( int j = 1 ; j <= word.length() - i ; j++ )
{
sub .append(word.substring(i, i+j)).append("\n");
}
}
return sub.toString();
}
Note: Consider using StringBuilder instead of String if you will do lots of concatenation on String.
I realize I'm a little late to this party, and I'm a very new programmer, myself -- but I was running into the same error last night while trying to write a similar method.
For me, it helped to rename the counter variables of the nested for loops to names that described what they are keeping track of. For the outer loop, I used int subLength, and for the inner loop, I used int position (starting position). I'm sure there are other ways of doing this, but I was happy with my solution. Here is some pseudocode that I hope will help someone else who looks this question up:
for each possible substring length 1 up to and including the original word length:
generate substrings starting at the 0th position, and then starting at each
proceeding letter up to but not including (word.length() - (subLength - 1))

String index out of range: n

Im having a bit of a problem with this code each time i execute it it gives me an error
String index out of range: 'n'
n - is the no. of characters that is entered in the textbox pertaining to this code...
(that is textbox - t2.)it is stuck at that first textbox checking it does not go over to the next as mentioned in the array.
Object c1[] = { t2.getText(), t3.getText(), t4.getText() };
String b;
String f;
int counter = 0;
int d;
for(int i =0;i<=2;i++)
{
b = c1[i].toString();
for(int j=0;j<=b.length();j++)
{
d = (int)b.charAt(j);
if((d<65 || d>90)||(d<97 || d>122))
{
counter++;
}
}
}
it is basically a validation code that i am trying to do without exceptions and stuff(still in the process of learning :) )
any help would be appreciated
thx very much.
Use <, not <= when iterating over the string. With <=, you get an out of bounds error, when j equals the length of the string. Remember that characters in the string are indexed starting from zero.
for(int j = 0; j < b.length(); j++)
In java string.charAt(string.length()) will be out of bounds since the string is 0 indexed and so the last character is at string.length() - 1.
Strings are indexed starting at 0. Your second for loop is set to end at b.length, which will always be 1 greater than the highest index for that string., Change it to j < b.length instead.

Categories

Resources