1

Im learning arrays and Im trying to reverse the order in an array. This is the method I've got this far but it's only working for the first half of the values in the array. What am I doing wrong?

public static void reverse(int[] anArray)
{
    int[] a = anArray ;
    for (int j = 0; j <= (a.length - 1); j++ )
    {
        anArray[j] = a[(anArray.length - j - 1)];
    }
}
Cody
  • 870
  • 4
  • 21
  • 38
  • 1
    once you stop learning arrays please use Collections.reverse – Oleg Mikheev Nov 11 '11 at 14:06
  • ok, Im not sure what that is yet but since were covering arrays in my university course I have to finish learning this first :(. – Cody Nov 11 '11 at 14:07
  • 1
    Before writing any code, see if you can write down/sketch out the steps that would have to happen for an array to be reversed. – mikej Nov 11 '11 at 14:08
  • yah basically logically it should be like: 1. duplicate the array as a new array (a). 2. Loop through each value in the initial array and make the nth value be nth value from the end of the duplicated array. Is there anything else to it? logically that's all you need, no? – Cody Nov 11 '11 at 14:10
  • possible duplicate of [How do I reverse an int array in Java?](http://stackoverflow.com/questions/2137755/how-do-i-reverse-an-int-array-in-java) – Deanna Apr 11 '14 at 08:19

9 Answers9

5

You need to make a temporary location in order to do the swap. This code write the end of the array to the front, but by the time you get to writing the end of the array, the first half of the values have already been lost.

public static void reverse(int[] a)
{
    int l = a.length;
    for (int j = 0; j < l / 2; j++)
    {
        int temp = a[j];
        a[j] = a[l - j - 1];
        a[l - j - 1] = temp;
    }
}

Additionally, you are incrementing j twice. The last part of the for loop definition does the increment between each loop. You don't need to do it manually inside the loop block.

The Alchemist
  • 3,397
  • 21
  • 22
unholysampler
  • 17,141
  • 7
  • 47
  • 64
2

This is not a difficult problem, and I'm sorry that you've received several wrong answers already.

Your goal is to reverse the contents of the existing array. Your idea is to assign to each array index from the corresponding one in order to switch them all around. However, this would only work if all the assignments happened simultaneously. The code actually runs one assignment at a time. Thus, when you get to the second half of the array, the indices that you're copying from have already been altered by previous runs of the loop.

To fix this, you need to swap pairs of indices. Loop up to halfway (since otherwise you'll swap each pair twice, and end up where you started); take the two indices and swap them. Now, for the reason we just discussed, you can't just assign one to the other and then vice-versa. Instead, you need to "remember" one of the values in a variable first. Assign into that index (since you have the old value saved) from the other one, and then finally assign the remembered value to the other index.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
1

If you are able to use Integer array, you could do like this:

    Integer[] anArray = {0,2,4,1}; // an array of Integer because List do not accept int as type.

    List<Integer> list = Arrays.asList(anArray);  // converting the array to List

    Collections.reverse(list); // reversing the "list" variable.

You can also use Guava's Lists.reverse(List) to create a view backed by the given list that is in reverse order without copying it or modifying the original list.

Jacobi
  • 1,508
  • 15
  • 29
  • 1
    Awesome, you can reverse an array with `Arrays.asList`! I thought it was read-only, but it's write-through. The only thing it doesn't support is length-changing operation (add/remove). – TWiStErRob Dec 13 '15 at 21:19
1

This reverses the source array by an in place technique. Basically, you are ONLY allowed to use the source array and cannot create another one.

public static void reverseArrayInPlace(int [] source){
    for(int col=0; col<source.length/2; ++col){         
        int temp=source[col];
        source[col]=source[(source.length-1)-col];
        source[(source.length-1)-col]=temp;
    }
}

//initially; 10 20 30 40 50 60

// col=0; 60 20 30 40 50 10

// col=1; 60 50 30 40 20 10

// col=2; 60 50 40 30 20 10

// col=3; 60 50 30 40 20 10

// col=4; 60 20 30 40 50 10

// col=5; 10 20 30 40 50 60

This is why we give the condition col<(source.length/2), if it went up to col<source.length then it would be arranged in the same manner it was before i.e, it wouldn't reverse. Try it both ways to see it yourself.

1
public static void swap (int[] a, int pos1, int pos2)
{
      int tmp = pos1;
      a[pos1] = a[pos2];
      a[pos2] = tmp;
}

public static void reverse (int[] a)
{
    int l = a.length;
    for (int j = 0; j < (l / 2); j++)
    {
        swap (a, j, l - j - 1);
    }
}

The variable l is just for brevity - it is not a recommendation.

  • The arrays content is mutable in Java, so you don't need a second one, which would only be a new reference to the same array.

Sorry - I missed to swap, of course.

user unknown
  • 35,537
  • 11
  • 75
  • 121
  • 4
    This will only work for the first part of the array aswell and leave the second half untouched. – Marcus Nov 11 '11 at 14:13
  • Okay, and now the second half of the array? – Karl Knechtel Nov 11 '11 at 14:15
  • 1
    Which would be fine if you'd actually written a swap. – Karl Knechtel Nov 11 '11 at 14:20
  • But in the process when switching you will overwrite the values later needed (if you don't use some temporary place to store the value). But in your case you don't even do a swap – Marcus Nov 11 '11 at 14:21
  • Oh - of course, I have to use "swap", not assignment. How foolish to publish without test! Thank you. – user unknown Nov 11 '11 at 14:27
  • I love the fact that the simplicity of this problem has become so complex to confront! – Bob Nov 11 '11 at 14:27
  • Why don't you just do the swap inside the loop instead of another function call for a simple thing like that? But yeah, it should work now :) – Marcus Nov 11 '11 at 18:40
  • Modularisation. DRY. A swap-method might be useful for different purposes. It can and should be tested separately. And 2 short methods are more easy to reason about, than one bigger one. – user unknown Nov 11 '11 at 18:51
1

When you write int[] a = anArray it will not be a copy of the array but a reference to the very same array. That's why it only works for the first half of the array since the when the second half of the array the first part has already been overwritten. To fix this you have to write:

int[] a = anArray.clone();
Marcus
  • 12,296
  • 5
  • 48
  • 66
  • oooh, ok, that makes more sense. Thank you – Cody Nov 11 '11 at 14:12
  • The explanation is correct but the proposed solution is dubious. If you just make a copy of the array and then apply the same algorithm to the copy, then you haven't made any progress. Further, the OP apparently does want to modify the original array. – Karl Knechtel Nov 11 '11 at 14:13
  • The OP assign the values to `anArray` thus operating on the original array. – Marcus Nov 11 '11 at 14:16
  • What's up with the down vote on this one? It works perfectly even though it's not the most optimized way to reverse an array. – Marcus Nov 11 '11 at 18:41
0

Here is the classic example for reversing using stack!

public static void main(String[] args) {
    int[] myIntArray = { 10, 20, 30, 40, 50, 60 };
    int [] reversedArray= new int[myIntArray.length];
    int reversedPosition=0;
    Stack<Integer> s = new Stack<>();
    for (int integer : myIntArray)
        s.push(integer);
    while (!s.empty()) {
        reversedArray[reversedPosition]=s.pop();
        reversedPosition++;
    }
}
Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35
0
public static void reverse(int[] anArray)
{
 int[] newArray = new int[anArray.length];
 int index = 0;
 for (int b = anArray.length - 1; b >= 0; b++)
 {
  newArray[index] = anArray[b];
  index++;
 }
}

Start an index off at 0, and take the last element from the "anArray" and put it at the index in the newArray;

user991735
  • 684
  • 1
  • 7
  • 15
  • `newArray` is not returned, so this does a bunch of work and throws it way at the end of the method scope. Also, you are incrementing `b`, while checking for when `b` becomes negative. – unholysampler Nov 11 '11 at 14:29
-1

Your problem is that you're reading the values out of the same array you're modifying.

public static void reverse(int[] originalArray) {
    int[] newArray = new int[originalArray.length];

    for (int i = 0; i < originalArray.length; i++) {
        newArray[i] = originalArray[originalArray.length - i - 1];
    }
}
Bryan Irace
  • 1,855
  • 2
  • 20
  • 38
  • 1
    ... which won't accomplish anything in the end, because the newArray is not returned and thus not usable anywhere. The OP wants to modify the original array. – Karl Knechtel Nov 11 '11 at 14:14
  • Yep, good point. Can do this instead: `public static void reverse(int[] originalArray) { int[] newArray = originalArray.clone(); for (int i = 0; i < originalArray.length; i++) { originalArray[i] = newArray[newArray.length - i - 1]; } }` – Bryan Irace Nov 11 '11 at 14:18
  • That is another valid approach. – Karl Knechtel Nov 11 '11 at 14:21