StringIndexOutOfBounds in Java - java

I have two exact copies of code here, except one has '<' in the for loops while the other has '<='. Could someone please explain why I get the index out of bounds exception when I use '<=', but then it works fine with '<'
Error code:
for(int i = 0; i <= str.length(); i++) {
int count = 0;
char currentChar = str.charAt(i);
for(int j = 0; j <= str.length(); j++) {
if (currentChar == str.charAt(j) ) {
count++;
Working code:
for(int i = 0; i < str.length(); i++) {
int count = 0;
char currentChar = str.charAt(i);
for(int j = 0; j < str.length(); j++) {
if (currentChar == str.charAt(j) ) {
count++;
If I don't use <= how will it compare the last character in the string?

Valid String indexes in Java, just like the indexes in any array, go from zero to length minus one. So clearly if you set up your condition to go up to i <= str.length(), you'll get outside the string.
Remember that a String on the inside is nothing more than a char[], and again: the valid indexes go from 0 to length-1. This is a convention, followed by many other programming languages that decided to start counting from zero instead of one.

Because you cannot access str.chatAt(str.length()) without throwing a exception.
a < b means "a is less than b" and it will be false when a equals to b.
a <= b means "a is less than or equals to b" and it will be true when a equals to b.
To compare the last character in the string, write some code to do so, compile and run.
bool res = currentChar == str.charAt(str.length() - 1); // assuming str has string with one character or more

str.length() returns the number of characters in the String. So "String".length() returns 6.
Now, when using indices, you start with zero. so "String".charAt(0) returns 'S'. "String".charAt(6) gives you a StringIndexOutOfBoundsException because the last character in "String" is at index 5.

String indexes begin at 0. str.length() returns how many elements are in your array. if you have a string
"dog"
"dog".length() = 3,
'd':0, 'o':1, 'g':2.
Since your for loop initializes i to 0, the working loop goes through indexes 0-2, which is 3 values, while the non-working one goes 0-3, and references a null, and str.charAt(3) does not exist.

Related

How would I allow this to go through every element to check if it is equal?

So I was trying to build a solitaire encryption program, but I keep running into a problem when it comes to this method. The char array a represents the word the user inputs (converted it into an array to make it easier) and the char array b represents the alphabets so it has 25 indexes. What I am trying to do is match the alphabet to its number. It seemed simple enough but I am having a hard time as it keeps throwing an ArrayIndexOutOfBoundsException. I have tried to use for loops, nested for loops and other tests but it keeps throwing the exception or just outputs unexpected results such as [0, 0, 0, 0, 0]. I have debugged it and it seems like b[i] never equals a[j] so j will always be 0.
public static int[] converter(char[] a, char[] b){
int[] res = new int[a.length];
int i = 0;
int j = 0;
while(i < a.length){
if(b[i] == Character.toUpperCase(a[j])){ //Does not run through the first loop at all
res[j] = i + 1;
j = j + 1;
} else {
i = i + 1;
}
}
return res;
}
Please do not link the similar question. It does not answer my question.
The code below is a solution. We want the wordCharacterIndex to iterate through the word to see the place where a character is. The characterIndex iterates through the characters to compare with the word's character present at the wordCharacterIndex. After setting the result, we need to reset the characterIndex so that it goes back to the first character in the character array to compare with the other word characters, if we didn't, the following characters of the word would need to be at a higher character index, which is not what we want. Naming variables actual words is very important to better understand what you are trying to do within your code. You were comparing i < a.length while you were iterating through b[i] which made it possible to go larger than b's bounds and therefore cause an ArrayIndexOutOfBoundsException. I hope this helps you better understand.
public static int[] converter(char[] word, char[] characters){
int[] result = new int[word.length];
int characterIndex = 0;
int wordCharacterIndex = 0;
while(wordCharacterIndex < word.length){
if(characters[characterIndex] == Character.toUpperCase(word[wordCharacterIndex])){
result[wordCharacterIndex] = characterIndex + 1;
wordCharacterIndex++;
characterIndex = 0;
} else {
characterIndex++;
}
}
return result;
}

How to find matching characters in two strings using regex java

In a given two words, is it possible to use regex to find multiple strings matching character as well index.
For example:
String1 = cat
String2 = carrot
the first 2 characters and indexes are matching (ca). t does not count because it is not in the same index.
I've tried for loop. However it appears to be not working and not very efficient.
for (int i = 0; i < string1.length(); i++){
for (int j = 0; j < string2.length(); j++){
char ch1 = string1.charAt(i);
char ch2 = string2.charAt(j);
if (ch1 == ch2) {
count char++;
}
}
What you are probably looking for is the longest common prefix.
See Find longest common prefix?
Regex is for pattern matching. It is a solution to a different problem.
For loop can still work for this job to find positions where each string has same char and number of times this occurs:
ArrayList<Integer> places = new ArrayList<Integer>();
for (int i = 0; i < Math.min(string1.length(), string2.length()); i++) {
a = string1.charAt(i);
b = string2.charAt(i);
if (a == b) {
count++;
places.add(i); //To say at which indices the 2 strings have the same chars
}
}
I guess you want to count the number of characters repeated at the same positions in two words. (Not same prefix)
In words cat carrot, you want to get 2 since c and a are in the same position, but t is not.
in words carrot cabra, you will get 3, since c, a and r (4th) are the same in the same position.
You only need to iterate one time over the two strings at the same time:
String string1 = "car";
String string2 = "carrot";
int minLength = Math.min( string1.length(), string2.length() );
int count = 0;
for (int i = 0; i < minLength; i++){
char ch1 = string1.charAt(i);
char ch2 = string2.charAt(i);
if (ch1 == ch2) {
count++;
}
}
We use minLength since we only need to check until the length of the smallest word.
We use string1.charAt(i) and string2.charAt(i), with same index i, since we want to check characters in the same position.

How to separate a string into substrings of two characters

I am trying to split strings in substrings of two chararters for example for the input: "ABCDE" i want to get the substrings "AB" "BC" "CD" "DE".
I tried with this:
String route = "ABCDE";
int i = 0;
while(i < route.length()) {
String sub = route.substring(i,i+2);
System.out.println(sub);
i++;
}
but the index (i) gets out of range int the last iteration and causes an error.
is there any way to do this without getting the index (i) out of range ?
You need to change the loop condition.
while(i < route.length()-1)
In your code i goes till (length-1) and than in the substring(i,i+2) function you gives end index i+2. It is higher than largest index of string.
Also, As far as I know calling a library function in a loop condition is not considered a good practice.
In each iteration you call this function which is time consuming.
control goes to that subroutine in each iteration.
A good alternative to this would be to store the length in a variable and use that in a condition.
int temp = route.length()-1;
while(i<temp){
This should work fine
String route = "ABCDE";
if( route.length() > 2){
int i = 0;
do {
String res = route.substring(i,i+2);
System.out.println(res);
i++;
} while (i + 1 < route.length());
}
else{
System.out.println(route);
}
Edit: Added boundary case for the string has length less than 2
Add check for the size of the string to trap the error:
String route = "ABCDE";
int i = 0;
while(i < route.length()) {
if(i < route.length() - 1) {
String sub = route.substring(i,i+2);
System.out.println(sub);
} else {
String sub = route.substring(i,i+1);
System.out.println(sub);
i++;
}
So whenever the i counter almost close to string size, get the last char.
You are getting an StringIndexOutOfBoundsException because you are trying to access an index of the String that doesn't exist.
To fix this, change your loop condition from
while(i < route.length())
to
while(i < route.length() - 1)
Without the -1 on the last iteration of the while loop i + 2 is equal to 71 which is out of the Strings bounds.
Another (cleaner) solution to this problem is a for loop:
for(int i = 0; i < route.length() - 1; i++) {
System.out.println(route.substring(j, j + 2));
}
The for loop in this situation is just shorter as the declaration, conditional, and increment statements are all in one line.
1: This 7 reduces to 6 since the endIndex of substring is exclusive.
As denis already pointed out, the bug in the code is in the loop condition.
Should be: while(i < route.length() - 1)
. However, how about simplifying this logic to use a for loop.
String route = "ABCDE";
for (int i=0; i+2<=route.length(); i++)
System.out.println(route.substring(i,i+2));
you can not use
i < route.length(),because when i = 5, String sub = route.substring(i,i+2); the i+2=7,is out of index,so use i<route.length instead

String out of range - java

I want get a String like this "SsjAasdLlswAasdMm"
and print a String like this "salam"
(print characters as String that are next to a Capital)
I wrote this :
import java.util.Scanner;
public class Temp {
public static void main(String[] args) {
char[] capitalalphabet = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
Scanner input = new Scanner(System.in);
String s1 = input.next();
StringBuffer s2 = new StringBuffer();
for (int i=0 ; i < s1.length() ; i++) {
for (int j = 0; j < capitalalphabet.length; j++) {
if (s1.charAt(i) == capitalalphabet[j]){
int k = 0 ;
s2.setCharAt(k , s1.charAt(i+1));
k++;
}
}
}
System.out.println(s2);
}
}
and i got this error :
SAhfdsdEDsa
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.StringBuffer.setCharAt(StringBuffer.java:257)
at Temp.main(Temp.java:14)
It happens at this line:
s2.setCharAt(k, s1.charAt(i+1));
According to the documentation:
Throws:
StringIndexOutOfBoundsException - if start is less than zero, or greater than the length of this object.
Since your s2 string is empty (its length is 0), you're exceeding the bounds when you try to add to it.
Also, since your k variable is always initialized to zero right before the setChatAt method, and it's only defined inside the if-statement block, you'll always be setting at index 0, even if you could.
I'd suggest you just simply try to use StringBuilder instead, as well as discard the messy loop of captial letters - their ASCII code is sequential, you could simply ask if character is in range:
for (int i=0 ; i < s1.length()-1; i++) {
char c = s1.charAt(i);
if (c >= 'A' && c <= 'Z') {
s2.append(s1.charAt(i+1));
}
}
System.out.println(s2);
Note that the loop scans until the index before last, since it might access the next index (and since there's no need to check the last character - it cannot be followed by anything, capital or otherwise).
Note you could also replace the if condition with Character.isUpperCase(c) which is more readable and elegant.

Sequentially searching two dimensional char array

I'm working with the following:
private char [][] board;
<various lines of code>
//Sequential searching for an index that has yet to be
//changed from the default char character
for(int i = 0; i< board.length; i++)
{
for(int j = 0; j>board[i].length; j++)
{
//Here I get the error "incomparable types: char and char[]
if('\u0000' == board[j])
System.out.println("Game unfinished.");
}
//Here I get the error "incomparable types: char and char[]
if('\u0000' == board[j])
System.out.println("Game unfinished.");
}
else return 'T';
In essence, I want to traverse the array, doing either one of two things:
If all array indexes are occupied by either 'X' or 'O' then return 'T' OR
If an array index is found with '\u0000' do:
System.out.print("Game unfinished.");
First, you'll want to add a null check, just in case. Then, fix the for condition as #libik indicated. Finally, reference the cell by its i and j indecies. e.g:
for(int i = 0; i < board.length; i++) {
//Always check for nulls, unless you're 100% certain of the data
if (board[i] != null) {
for(int j = 0; j < board[i][j].length; j++) {
//Here I get the error "incomparable types: char and char[]
if('\u0000' == board[i][j]) {
System.out.println("Game unfinished.");
}
}
}
Regarding the second if statement and the return 'T', these don't make sense as they stand. Did you want to return 'T' if no '\u0000' chars where found in the array? If so, create a boolean flag, initialize it to false, then set it on the else condition of the if statement above. Outside of the loop, add a second if to see if the flag was ever set and return 'T'.
You have two mistakes.
First change j>board[i].length to j<board[i].length
Then you have to compare char to char, in 2D char, you have to specify both dimension, to get char, specify only one means you only specify row or column of chars (thus it is array of char).
Comparing should look like this : if('\u0000' == board[i][j])

Categories