Ryan Fu
Ryan Fu

Reputation: 349

How to reverse slice of array java

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?

Upvotes: 0

Views: 1282

Answers (2)

hfontanez
hfontanez

Reputation: 6178

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.

Upvotes: 2

Gurkirat Singh Guliani
Gurkirat Singh Guliani

Reputation: 1015

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  

Upvotes: 3

Related Questions