2

I've been trying to do something simple like reversing an array using 2 nested for loops, but I've been having trouble doing so.

#include <iostream>

using namespace std;

int main() {
  int arr[] = {1,2,3};
  int index = 0;
  int length = sizeof(arr)/sizeof(arr[0]);
  int temp;


  // Before reverse
  cout<<endl;
  for (int j = 0; j < length; j++)
    {
      cout<<arr[j]<<" ";
    }


  for(int l = 0; l < length-index; l++)
    {
      // swap elements
      for(int i = 0; i < length-1; i++)
        {
          temp = arr[i];
          arr[i] = arr[i+1];
          arr[i+1] = temp;
        } 
      index++;
    }


  // After Reverse 
  cout<<endl;
  for (int k = 0; k < length; k++)
    {
      cout<<arr[k]<<" ";
    }

}

Using this for loop alone, I can get the first index to the end. However, when I use another for loop, I try decrementing the length so that the first index, that was moved to the end, does not get moved, but I it doesn't work. The first index at the end continues to move and I do not want that to happen

for(int i = 0; i < length-1; i++)
        {
          temp = arr[i];
          arr[i] = arr[i+1];
          arr[i+1] = temp;
        } 

Please help.

cindicate
  • 93
  • 5
  • With pen and paper, apply your algorithm. You'll find the solution quick enough. Pen and paper: the best designing tools. – YSC May 04 '23 at 22:34
  • You'll be glad to hear you don't need anyone's help to figure this out, just a tool you already have: your debugger! This is exactly what a debugger is for. It [runs your program, one line at a time, and shows you what's happening](https://stackoverflow.com/questions/25385173/), this is something that's every C++ developer must know how to do. With your debugger's help you'll able to quickly find all problems in this and all future programs you write, without having to ask anyone for help. Have you tried using your debugger, already? If not, why not? What did your debugger show you? – Sam Varshavchik May 04 '23 at 22:36
  • Is there a requirement for nested loops? You can do this with a single loop, going from *bottom* to *top*, appending to a new array. – Thomas Matthews May 04 '23 at 22:37
  • 1
    It is not necessary to append to a new array, unless you want to avoid swaps. You can do it in-place with a single loop, using swaps. Or you can use [std::reverse](https://en.cppreference.com/w/cpp/algorithm/reverse) -- and note in the documentation link there is a "possible implementation" section that basically shows you how you can do it yourself. But in a pinch: `std::reverse(arr, arr + length);` is all you need. – paddy May 04 '23 at 22:41

1 Answers1

0

As currently written, your "reverse" algorithm is trying to bubble elements through the array by swapping with their neighbor. Not only is this very inefficient, but it will simply not work.

You can use swaps to reverse an array, but you should do this from each end of the array. For instance, swap the first and last elements, then the second and second-to-last elements, etc until you reach the middle of the array.

for(int left = 0, right = length - 1; left < right; left++, right--) {
    swap(arr[left], arr[right]);
}

Here we just use the standard library's std::swap function. It's written here with no namespace qualifier, since you imported the entire std namespace -- generally not a good idea, but nevermind.

But if you can use the standard library's swap, you may as well use reverse as well! Full example:

#include <algorithm>
#include <iostream>

// Write contents of array to stdout
template <typename T, std::size_t size>
void print(const T (&arr)[size]) {
    for (auto& x : arr) std::cout << x << " ";
    std::cout << "\n";
}

// Reverse an array
template <typename T, std::size_t size>
void reverse(T (&arr)[size]) {
    std::reverse(arr, arr + size);
}

int main() {
    int arr[] = { 1, 2, 3 };
    print(arr);
    reverse(arr);
    print(arr);
}

Otherwise, implementing your own swap and reverse:

#include <iostream>

// Write contents of array to stdout
template <typename T, std::size_t size>
void print(const T (&arr)[size]) {
    for (auto& x : arr) std::cout << x << " ";
    std::cout << "\n";
}

// Swap elements
template <typename T>
void swap(T& a, T& b) {
    T a_orig = std::move(a);
    a = std::move(b);
    b = std::move(a_orig);
}

// Reverse an array
template <typename T, std::size_t size>
void reverse(T (&arr)[size]) {
    if (size > 1) {
        for(std::size_t left = 0, right = size - 1; left < right; left++, right--) {
            swap(arr[left], arr[right]);
        } 
    }
}

int main() {
    int arr[] = { 1, 2, 3 };
    print(arr);
    reverse(arr);
    print(arr);
}
paddy
  • 60,864
  • 6
  • 61
  • 103