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--;
}
}
I have a basic question about the inner loop length in Java selection sort. Here is the commonly used code for selection sort:
package com.java2novice.algos;
public class MySelectionSort {
public static int[] doSelectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int index = i;
for (int j = i + 1; j < arr.length; j++)
/* why not the length is not arr.length-1? I think the length is
exactly the same as what it is, the array's length is a
static number as array.length-1, but when it comes to the inner
loop why it plus 1 to the array length? */
if (arr[j] < arr[index])
index = j;
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
}
return arr;
}
}
Imagine you're trying to sort five items. The array length is 5, which means the indexes are 0 through 4.
In the first iteration of the inner loop, you have i=0 and j=1. You need j to index to the end of the array. That's why the expression in the inner loop is j < array.Length.
i, of course, only goes from 0 to 3, which is why the outer loop has i < array.Length - 1.
If you lay five playing cards on a table and walk through the steps of the selection sort, you'll get a better idea of what's happening here.
the first loop does not need to check the last index, therefore, it goes to arr.length - 1. on the second loop, of course, the last index of the array must be checked so the loop goes to the last index (arr.length).
imagine if the first loop goes to the last index. then this line for (int j = i + 1; j < arr.length; j++) will never execute.
check out this Pseudo code of selection sort for a better understanding of the algorithm
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--)
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
I'm trying to populuate an array with random numbers to be sorted and used in a binary search. All of my code seems to work fine except the generating part. The numbers need be between 1-32767 and I continue to get 0.
for(int i = 0; i < SIZE-1; i++){
array[i] = (gen.nextInt(32767 - 1) + 1);
}
// Print out five entries
for(int i = 0; i < 5; i++){
System.out.println(array[i]);
}
// Sort array
Arrays.sort(array);
// Print out first five sorted entries
for(int i = 0; i < 5; i++){
System.out.println(array[i]);
}
After they're sorted and printed, the first entry is always 0. Perhaps this has to do with the array sorting, and I'm not realizing it. Any suggestions?
You're never setting the last element of the array -- use i < SIZE, not i < SIZE-1.