I've been attempting to reverse a slice of a list in java.
The equivalent in python (though perhaps not the best way - I don't care about this, just want to get my point across) would be:
myList = [0,1,2,3,4,5,6,7,8,9,10]
reverseSlice = myList[2:6]
reverseSlice.reverse()
myList[2:6] = reverseSlice
When I tried to manually implement this in Java, I tried this:
public static int[] reverse(int[] x,int a1, int a2) {
a1--;
int[] rArr = new int[a2-a1+1];
for (int ind = a1; ind<a2; ind++) {
rArr[a2-ind-1] = x[ind];
}
for (int ind = a1; ind<a2; ind++) {
x[ind] = rArr[ind];
}
return x;
}
However, when I run this:
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
for (int i : cows1) {
System.out.print(i + " ");
}
I get 0 4 3 2 1 0 6 7 8 9 10 .
I'm really confused how I got this, as in my function, I don't introduce new values, so the "0" shouldn't have appeared.
My Question: Why is my code returning values that are not in the list?
The 0 value which is coming might be because of accessing an uninitialized value from rArr array. For the purpose of reversing, an extra array is not required. You can simply swap the values from the starting index to the end index. I have tested the following code and it gives correct output
public class Solution2 {
public static void main(String args[])
{
int[] cows1 = new int[]{0,1,2,3,4,5,6,7,8,9,10};
cows1 = reverse(cows1,2,6);
// both indices are inclusive
for (int i : cows1) {
System.out.print(i + " ");
}
}
public static int[] reverse(int[] x,int a1, int a2) {
for (int i = 0; i < (a2-a1+1)/2; i++) {
swap(x,a1+i,a2-i);
}
return x;
}
private static void swap(int[] x, int i, int j) {
// System.out.println("values swappeed are "+ x[i] + " " + x[j]);
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
and the output comes as
0 1 6 5 4 3 2 7 8 9 10
The problem seems to be the first line of your reverse function: a1--; not preserving the original value for your start index.
The method call
The purpose of the reverse function is to reverse only the portion of the array bound by variable values a1 and a2. On a side note, never use meaningless names like that. Better names for these variables could've been startIndex and endIndex or similar naming (a1 and a2 don't really mean anything).
For values (2, 6), the reverse function should extract the portion of the array starting at index 2 and ending on index 6. I am assuming the end index is not inclusive, so it should only grab values at index 2, 3, 4, and 5. However, the first thing the method does is decrement the start index, so it actually starts at index 1.
From there, the function successfully reverse the values located at these indices [4,3,2,1]. The question is now, what happens to the value at index 5? Let's see what this part of the code does new int[a2-a1+1]. The value of a2 is 6 and the new value of a1 is 1 because it was decremented in the first line. That means that your new array is of size [6-1+1] which is 6. That seems to be incorrect. Only 4 values are required to be reversed and the array is one element too big. The last index of this array is defaulted to integer value of 0.
The swap
First loop:
for (int ind = a1; ind<a2; ind++) { // starts with a1 = 1 and a2 = 6
rArr[a2-ind-1] = x[ind]; // rArr[4] = x[1]: first iteration is off by 1
}
Second loop:
for (int ind = a1; ind<a2; ind++) { // a1 = 1, a2 = 6 (starts at 1 and ends at 5 (rArr doesn't have an index 5)
x[ind] = rArr[ind]; // first iteration: x[1] = rArr[1], last iteration x[5] = rArr[5] -> this last index is accessible because array was too big and was initialized to a primitive `int` default value (0).
}
The solution
Make sure your start and end indices are preserved.
Allocate the temp array (if needed) using the original start and end indices for your calculation.
Inside the reverse() method, your first line should've been:
int[] rArr = new int[a2-a1]; // allocates an array of size 4 (6-2)
From here, if the rest of the method is wrong, you will not see a zero anywhere in the reversed array. At worst, you would've seen an offset problem if your start index was erroneously calculated. And that, I think, would've been easy to spot and fix.
If you are new at programming, and even if you are more of an "expert", you should always work out these problems on paper (or on a board) before you attempt to code and walk through your logic. You will be amazed as to how many logic errors you will catch before you code.
I'm trying to add the functionality to remove an item from an array via method call but am running into the problem posted in the title.
Heres the instructions:
Write a new method for the ArrayIntList class called remove that takes an integer index and that removes the value at the given index, shifting subsequent values to the left. For example, if a variable called list stores the following values:
[3, 19, 42, 7, -3, 4]
after making this method call:
"list.remove(1);"
would remove 3 from the array (not this is not specific to just the first value of the array
I tried to implement doing this:
public void remove(int index) {
int target = index;
int[] elementDataCopy = new int[size];
size = elementData.length;
if (index < 0 || index >= size) {
throw new IllegalArgumentException("invalid index");
}
//loop through each value until the index given is == to loop value
//create a copy of elementData where length is one less and value at
//index given is not present
//each time something is removed, the tracked values decrease by one
size--;
for(int i = 0; i < elementData.length + 2; i++){
if (elementData[i] == target){
continue;
}else{
elementDataCopy[i] = elementData[i];
}
}
}
``
but get this error:
Failed: Index 12 out of bounds for length 12
with the numbers differing depending on what input is.
note that elementData is an array of ints and index is an int that is pointing at a point in said array
all help is appreciated, pretty sure this is something basic
Try it like this. The big mistake is using i for both source and destination indices. Use a separate one (k here) for destination. Only increment the destination index when the copy is made. Once done,
reassign the elementDataCopy to elementData.
int k = 0;
for(int i = 0; i < elementData.length; i++) {
if (i == index) { // skip the one to "delete"
continue;
}
elementDataCopy[k++] = elementData[i];
}
elementData = elementDataCopy;
I have a problem with one of our old exam tasks.
the task is
"the method positions should return a field containing exactly the positions of those elements of the list that have null as content. if there are no such elements than return a field with the length 0"
the code starts with :
public int[] positions() {
int[] result = new int[0];
I keep getting stuck on because of the "new int[0]" when I tried solving the problem without it I managed to get somewhat of a result. but I don't know how to do it with this part.
Just think for a moment what the code is doing here.
int[] result = new int[0];
creates an empty, fixed lenght, primitive array. This array cannot be further expanded.
Your exam task would be translated as (simplifying at a large degree):
public int[] positions(final Object[] objects) {
// Initialize the array with the max possible size, which is the input array size
final int[] positions = new int[objects.lenght];
int j = 0;
for (int i = 0; i < objects.length; i++) {
if (objects[i] == null) {
// Assign the index of the null value to the holder array.
// Increment j, which is the index of the first free position in the holder array
positions[j++] = i;
}
}
// This will return a copy of the "positions" array, truncated at size j
return Array.copyOf(positions, j);
}
The purpose of this method is to return the position (subscript index) of the largest element in the array (not its value, but its position). If the same maximum value appears more than once in the array, then it should return the position of the first or earliest on. If the array has no elements it should just return -1.
The solution:
public static int maxPos(int[] arr) {
int pos = 0;
if(arr.length > 0 ) {
for(int i = 0; i < arr.length; i++) {
if(arr[i] > arr[pos]) {
pos = i;
} else {
pos = - 1;
}
}
return pos;
}
I understand setting up a dummy variable "pos" to represent the index position of the maximum value of the array. And having the check point with if(arr.length > 0) then proceed. And the for-loop to sift through the entire array checking one-by-one which index has the greatest number value and after each iteration either re-assigning dummy variable or carrying onward.
The part where I get lost is when using things within the array [ ]'s, it throws me off. I don't think anywhere else in java there is such notation. For example with arrayList wouldn't that just be nameOfAL . get();
So the equivalent of that for an array is using the []'s?
I am a bit confused by arr[i] > arr[pos].
Is this to say when we are at the i'th index in the for-loop, we can then use arr[] and put something within that box, and when we do it outputs the value of that index. So anytime we put something within that array box it's always going to output an index position? is that the purpose of putting things inside the [] box? it will output the value of whatever is put inside it's brackets.
the next part that confuses me is why pos = i?
I understand if the if-statement fails then the else is - 1. but why return pos; after each iteration?
Thank you
Your posted code contains a few bugs, you should start with pos at -1 (instead of resetting it when a given value isn't greater then the current max). Also, I would check for null. Then you can start your loop with the second element. Something like,
public static int maxPos(int[] arr) {
int pos = -1; // <-- indicates no elements.
if (arr != null && arr.length > 0) {
pos = 0; // <-- there is at least one element.
for (int i = 1; i < arr.length; i++) {
if (arr[i] > arr[pos]) {
pos = i; // <-- update the max position
}
}
}
return pos;
}
First, so what you're putting in the square braces are variables named i and pos that hold the values of the numerical positions you're accessing in the array. It's like the get method of the arrayList class like that.
It's not returning pos until it finishes the for loop. In general it's returning pos because that's the index of the largest number, which is the point of the program. I think you're just missing a bracket somewhere, you have 5 {'s and 4 }'s.
This question already has answers here:
How do I remove objects from an array in Java?
(20 answers)
Closed 8 years ago.
I am beginner to java coding, I am facing some complexity in updating the array.
My problem is I have an array named s1[] which consists of 10 elements from that I have to choose 1st 3 elements and I have to store in one array i.e. max1[] array and in next array I have to choose randomly 3 elements from the same array i.e. s1[] and store it in max6[] and I need to do comparison between the two arrays i.e. max1[] and max6[] so that the matching values will be stored.
My code looks like this (here f1 = 3)
for (i1 = 0; i1 < f1; i1++) {
max1[i1] = s1[i1];
System.out.println("1st tree random leaf nodes of phy m/c 1 at tree 1 : " + max1[i1]);
System.out.println(" \n ");
max6[i1] = s1[(int) (Math.random() * f1)];
System.out.println(" random leaf nodes of phy m/c 1 at tree 2: " + max6[i1]);
System.out.println(" \n ");
}
for (int l1 = 0; l1 < f1; l1++) {
for (int k1 = 0; k1 < f1; k1++) {
if (max1[l1] == max6[k1]) {
c1[l1] = max1[l1];
k1++;
System.out.println("the value after crossover is:--------->" + c1[l1]);
break;
}
}
}
now what I want is that I have to repeat the loop for some iterations so that in the next iteration the values of the max1 array in 1st iteration shouldn't be repeated means I have to permanently remove the elements from s1 array until s1 array contains zero elements in it
I have two suggestions for you, it's up to you which you prefer.
Firstly I would suggest converting the array to a list and removing the necessary elements from the list then converting back to the array. Code follows :
List<Double> list = new ArrayList<Double>(Arrays.asList(s1));
list.remove(i1);
s1 = list.toArray(new Double[0]);
Secondly you can shift the specific element of the array to the back and just iterate one position less than the length. This will require you adding an extra int variable to either record the number of elements in the array or to record the amount of deleted elements, the former being the better idea. Code follows :
double temp;
for(int i = 0; i < test.length - 1; i++){
temp = s1[i];
s1[i] = s1[i + 1];
s1[i + 1] = temp;
}
nrE = nrE - 1;
This will require you to have an int nrE with value of the length of the array(here 10) before your first for loop.
Both of these should be implemented inside the for loop at the end of the iteration.
From what I've seen my first suggestion is used most.
Note : I may misunderstand what you are trying to achieve, but I believe your code for getting the 3 random elements is faulty. If f1=3 and you take element at the position Math.random() * f1 you will always get an element in the range 0 to 3. To fix this you can instead use Math.random() * s1.length