How to mix strings the way I am looking for? - java

First of all, keep in mind I am new at this, so smart guys, be nice!
I am trying to understand why in this line:
for(i = word.length() -1; i >= 0; i--)
System.out.print(word.charAt(i));
I get my string replied to me backwards fine (answer: oaiCgiiB), and in this line of code:
for(i = 0 ; i <= word.length(); i++)
System.out.print(word.charAt(i));
I get an error...
Beijing ChicagoException in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(String.java:646)
at p200548.main(p200548.java:43)
I want the second one to work like the first one but instead of output BiigCiao
Any help would be appreciated.

Because you are out of bounds.
While:
for(i = word.length() -1; i >= 0; i--)
System.out.print(word.charAt(i));
for length = 3, uses the indexes 2, 1, 0, the following:
for(i = 0 ; i <= word.length(); i++)
System.out.print(word.charAt(i));
uses the indexes 0, 1, 2, 3. And 3 is out of bounds for length = 3.
You probably want:
for(i = 0 ; i < word.length(); i++)
System.out.print(word.charAt(i));
which would use the indexes 0, 1, 2.

for(i = 0 ; i <= word.length()-1; i++) //add mines 1 here
System.out.print(word.charAt(i));
you have to add -1 to ;word.length()-1;
because word starts at index "0" and ends with "word.length()-1"

In C language you would not get an exception because it does not care about crossing bounds of an array. This is one of the problems in C. Java, however always checks for bounds and gives you a 'IndexOutOfBoundsException' whenever you try to access an index outside array.
An equivalent code in C:
for(i = 0 ; i <= strlen(word); i++)
printf("%c",word[i]);
would work fine as word[length] is '\0' and there is no problem printing it

Related

Manual array copy in a nested for loop

I trying to find all 2s, move them to the back of the array, and turn them into 0s without loosing the order of the array. For example, [1,2,3,2,2,4,5] would become [1,3,4,5,0,0,0]. My code works fine but the IDE is telling me that the nested for loop is copying the array manually and wants me to replace it with System.arraycopy(). How would I go about that?
Code looks like this:
int[] numbers = {1,2,3,2,2,4,5};
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == 2){
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
numbers[numbers.length-1] = 0;
i --;
}
}
The following statement:
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
Can be replaced by:
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
IDEs like IntelliJ should suggest that automatically when you press alt + enter (default key combination).
Now about arraycopy()
From the documentation, java.lang.System.arraycopy() will copy n elements (last argument) from the source array (1st argument) to the destination array (3rd argument) with the corresponding indexes to start from (2nd and 4th arguments).
More specifically, when calling arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i) the arguments are:
numbers: The source array.
i + 1: The starting position in the source array.
numbers: The destination array.
i: The starting position in the destination data.
numbers.length - 1 - i: The number of array elements to be copied.
In your case, elements will be copied from your array, to itself, but the fact that source starting position is shifted from the destination starting position will induce the global shifting you're after (moving elements to the left).
About the number of elements to be moved, it should move i elements minus the first one that doesn't move and only gets overwritten. Hence the length - 1 - i.
The inner loop could be replaced with an arraycopy, however, you don't need an inner loop:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int i = 0; i < numbers.length; i++){
if (numbers[i] != 2){
numbers[j++] = numbers[i];
}
}
while (j < numbers.length) {
numbers[j++] = 0;
}
UPDATE
Or even:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int n: numbers){
if (n != 2){
numbers[j++] = n;
}
}
Arrays.fill(numbers,j,numbers.length,0);
The key thing is pretty simple: if you can reduce the lines of code you are responsible for (for example by using utility methods such as Arrays.arraycopy()) - then do that.
Keep in mind: each line that you write today, you have to read and understand tomorrow, and to probably modify in 5 weeks or months from now.
But then: I think you are over-complicating things here. I would use a temporary list, like this:
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
if (source[i] == 2) {
numberOfTwos++;
} else {
notTwo.append(source[i]);
}
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
You see: you are nesting two for-loops, and you are repeatedly copying around elements. That is inefficient, hard to understand, and no matter how you do it: way too complicated. As shown: using a second list/array it is possible to "solve" this problem in a single pass.
After replacing your inner loop with System.arrayCopy the code should look like:
int[] numbers = { 1, 2, 3, 2, 2, 4, 5 };
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 2) {
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
numbers[numbers.length - 1] = 0;
i--;
}
}

Java - out of bounds exception

I am receiving the following error: java.lang.StringIndexOutOfBoundsException and I can't figure out why. Hopefully one of you knows a solution.
Thanks in advance.
static boolean palindromeCheck(String toBeChecked) {
String reverse = "", inputWithoutSpaces = "";
for (int i = 0; i < toBeChecked.length(); i++)
inputWithoutSpaces += toBeChecked.charAt(i);
for (int i = inputWithoutSpaces.length(); i > 0; i--) {
if (inputWithoutSpaces.charAt(i) != ' ')
reverse += inputWithoutSpaces.charAt(i);
}
return (inputWithoutSpaces == reverse) ? true : false;
}
charAt() accepts indices from 0 to length()-1, not from 1 to length().
The problem is here: for (int i = inputWithoutSpaces.length(); i > 0; i--)
Lets say the inputWithoutSpaces has length 10. i.e. indices 0 to 9. In your loop you start counting from the index inputWithoutSpaces.length() which is 10. Which does not exist. Hense the out of bounds exception.
Change it to for (int i = inputWithoutSpaces.length() - 1; i >= 0; i--) so you count from 9 to 0.
Your string has a specific length (lets say length: 5), but when you want to reverse iterate it you need to start from 4 and got down to 0. This means that you need to change your for loop and make it like this:
for (int i = inputWithoutSpaces.length() - 1; i >= 0; i--)

counting the elements of array

I have an array which has null elements also. I want to keep track of number of elements that have the contents in it.
int counter = 0;
for (int a = 0; i <=array1.length; a ++){
if (array1[a] != null)
counter ++;
}
I used the above code for it. But I am getting ArrayIndexoutofBound exception at line
if (array1[a] != null)
why is that? Can someone point it pls.
Replace
for (int a = 0; i <=array1.length; a ++){
by
for (int a = 0; i <array1.length; a++){
Your code fails on element array1[array1.length], because the index must be between 0 and array1.length - 1 inclusive.
array1.length is the size of the array, but since the index is 0-based, you can only go to array1.length-1. So, either change your a <= array1.length to a <= array1.length - 1 or change it to the more common a < array1.length.
Change
for (int a = 0; i <=array1.length; a ++){
into
for (int a = 0; i <array1.length; a ++){
There is no element array1[array1.length]
If you have size of 5 array means you have index from 0 to 4, In other word index of the first element is 0 and the index of last element is 4
Of course it is because you are iterating one time extra than the length of an array.
If the length of your array is 3. Your array stores elements like array[0], array[1] and array[2].
Index of an array or any list Map Set starts from 0.
Use for(int a = 0; a < array1.length;a++)
In your "for" loop,it should be "a<=" instead of 'i'
switch <= to < in your for loop

Recursive word searching to find various versions of a word

I wish to iterate through a word and print out all the different variations of it. I have wrote the code but for some reason i keep on getting an StringIndexOutOfBoundsException.
public class Test {
public static void main(String[] args) {
String word = "telecommunications"; // loop thru this word
for (int i = 0; i < word.length(); i++) {
for (int j = 0; j < word.length(); j++) {
System.out.println(word.substring(i, j + 1));
//This will print out all the different variations of the word
}
}
}
}
Can someone please tell me why I am getting this error?
Remember, arrays are zero-based in Java (and most languages).
This means, that if you have a String of length N, the indexes will be from 0 to N - 1 - Which will have a total sum of N.
Look at this line:
System.out.println(word.substring(i, j + 1));
The length of your string is 18, the indexes are from 0 to 17.
j and i runs on this indexes, but what will happen when you do j + 1 in the last iteration?
- You'll get 17 + 1, which is 18, which is out of bounds.
j | char at j
----+-------------
0 | t
1 | e
... | ...
... | ...
17 | s
18 | :(
I won't tell you the solution, but it's straight forward when you know why this is happening.
The reason for exception is word.substring(i, j + 1).
Suppose, you are iterating through and having i=1 & j=17, in that case you are trying to extract the sub-string starting from position 1 and till i+j+1 = 19th position, whereas you string holds only 18 characters or positions.
I think you want to do something like this
for (int i = 0; i < word.length(); i++) {
for (int j = i; j <= word.length(); j++) { // Change here
System.out.println(word.substring(i, j)); // Change here
//This will print out all the different variations of the word
}
}
You get the exception because when you try to access j+1 with the last index, the index goes out of bounds as the max possible accessible index in any array or arraylist or string is always n-1 where n is the length.
Because word.substring(i, j + 1)
Here j value should be greater than i value. because first two iterations it will work fine.when third iteration i=2 j=0 at that time word.substring(2, 0 + 1) at this condition String index out of range: -1 will come because we cannot go back word substring. second argument should be greater than first argument

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