8

Okay so I've tried to print and Array and then reverse is using another array But I'm trying to create a For Loop that will take an array and reverse all of the elements in place without me having to go through the process of creating an entirely new array.

My for loop is running into some problems and I'm not sure where to go from here...i'm using i to take the element at the end and move it to the front and then j is being used as a counter to keep track of the elements...if there is an easier way to do this Any suggestions would be appreciated.

I'm New to this programming language so any extra info is greatly appreciated.

#include <stdlib.h>
#include <time.h>

int Random(int Max) {
  return ( rand() % Max)+ 1;
}

void main() {
  const int len = 8;
  int a[len];
  int i;
  int j = 0;
  Randomize() ;

  srand(time(0));
  //Fill the Array
  for (i = 0; i < len; ++i) {
    a[i] = rand() % 100;
  }

  //Print the array after filled
  for (i = 0; i < len; ++i) {
    printf("%d ", a[i]);
  }
  printf("\n");
  getchar();

  //Reversing the array in place.
  for (i = a[len] -1; i >= 0, --i;) {
    a[i] = a[j];
    printf("%d ", a[j]);
    j++;
  }


}
rw.liang1
  • 418
  • 4
  • 12
Zanderg
  • 159
  • 2
  • 5
  • 11
  • `void main()` may be allowed for your implementation, but better use standard `int main(void)` or `int main(int argc, char* argv[])`. – Deduplicator Apr 10 '14 at 03:16
  • ya i did actually run into this warning. its weird cause when i use Xcode it always starts off my Main that way. so it never occurred to me to change it. @Deduplicator – Zanderg Apr 10 '14 at 03:56
  • So file a bug report with Xcode, unless they are explicitly only for platforms having that extension (which i doubt). – Deduplicator Apr 10 '14 at 16:06

12 Answers12

15

A while loop may be easier to conceptualize. Think of it as starting from both ends and swapping the two elements until you hit the middle.

  i = len - 1;
  j = 0;
  while(i > j)
  {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
    i--;
    j++;
  }

  //Output contents of now-reversed array.
  for(i = 0; i < len; i++)
    printf("%d ", a[i])
rw.liang1
  • 418
  • 4
  • 12
  • When i use my printf statement I'm going to be printing a[i] and a[j] together since they are both half of the array. So once i do that it's not organizing them correctly. My return array looks something like this @liangricha 80 66 36 81 44 4 43 90 // 66 43 36 4 81 44 81 44 – Zanderg Apr 10 '14 at 04:21
  • What I'm noticing is that i and j are grabbing every other element instead of all the elements in that half. so my array is coming out all mixed up. @liangricha – Zanderg Apr 10 '14 at 04:24
  • @Zanderg not sure if I understand. If you march through the elements of array "a" after the while loop(reversal), and print them out one-by-one, the output should be the reverse of your first printf loop. – rw.liang1 Apr 10 '14 at 04:25
  • Ok so after debugging it i know it works...my problem is the way i am printing it. Putting it after the {} for the While loop makes the program skip over the "printf" completely. but if i put the "printf" inside the loop it will place a number each time it goes through the loop and not after it's finished. I tried an if (i == j) then "printf" but that doesn't work either. i know its all in my placement i just can't figure out where it goes. @liangricha – Zanderg Apr 10 '14 at 05:40
  • Edited my answer. You need to write another for-loop after the while-loop to print the contents of the array @Zanderg – rw.liang1 Apr 10 '14 at 05:45
  • What is more complicated in `for (i = len - 1, j = 0; i > j; i--, j++) ...`? – chqrlie Aug 06 '18 at 15:00
5
void reverse_range(int* buffer, int left, int right)
{
    while (left < right)
    {
        int temp = buffer[left];
        buffer[left++] = buffer[right];
        buffer[right--] = temp;
    }
}

call it to reverse array

int a[3] = {1, 2, 3};
reverse_range(a, 0, 2);
zdd
  • 8,258
  • 8
  • 46
  • 75
  • The API is questionable: should `right` be included as in the posted code or excluded to allow for empty ranges? The latter is a more common idiom in C and a widely used convention in the C++ library (with pointer ranges). – chqrlie Aug 06 '18 at 15:18
2

You are on the right track but need to think about that last for loop a little more and the assignment operation inside. The loop initialization is off, since i = a[len] - 1 will copy the value of the last entry to i. Since that value is a random number, your index will probably start out of bounds.

Next, you're copying half of the array to the other half and then back. That loop does the following: a[7] = a[0] a[6] = a[1] a[5] = a[2] a[4] = a[3] ...

At this point you've lost all of the initial values in a[4] through a[7].

Try this:

for( i = 0; i < len / 2; i++ ){
    int temp = a[i];
    a[i] = a[len - i];
    a[len - i] = temp;
}

Use a debugger and step through the loop watching the value of i, temp, and each element in the array

Chris Ryding
  • 1,508
  • 11
  • 16
1

Just my 2 cents...

#include <stdlib.h>
#include <stdio.h>

int main() {
      int arry[] = {0, 1, 2, 3, 4, 5};
      int* s = arry;
      int* e = arry + (sizeof(arry) / sizeof(arry[0])) - 1;
      while (s < e) {
        *e ^= *s;
        *s ^= *e;
        *e ^= *s;
        s++;
        e--;
      }
      for (size_t i = 0; i < (sizeof(arry) / sizeof(arry[0])); i++) {
        fprintf(stderr, "%d, ", arry[i]);
      }
      fprintf(stderr, "\n");
   }
Myst
  • 18,516
  • 2
  • 45
  • 67
  • I was wondering does this work for non-integer types, for example can you XOR `char`? – Celeritas Aug 17 '16 at 06:47
  • 1
    All core types in C are integer types... `char` is an 8bit integer with a bad name (on some systems it will be more then 8 bits). So, to answer your question, yes. Pointers should be cast to `intptr_t` before arithmetics are performed (this is for compiler and intention clarity reasons, not because pointers aren't numbers). – Myst Aug 17 '16 at 06:51
  • However, lately I have been advised that compilers optimize the `tmp` variable better then they do the XOR swap. There's a [wikipedia article about this](https://en.wikipedia.org/wiki/XOR_swap_algorithm#Reasons_for_avoidance_in_practice)... I have no idea if that's true. – Myst Aug 17 '16 at 06:55
  • 1
    yes it is a bad idea as it makes the code unreadable and the compiler does this anyways. That's why I was hesitant to give +1 but since you do say "Just my 2 cents..." :) – Celeritas Aug 17 '16 at 07:20
  • An interesting classical curiosity, but potential undefined behavior, slower on architectures where it works. Undefined behavior for empty arrays. – chqrlie Aug 06 '18 at 15:15
  • How come this would be undefined behavior for empty arrays? After all, if end equals start (`e == s`), nothing really happens (except printing an a new line marker). – Myst Aug 06 '18 at 18:42
0

For starters, instead of this:

for (i = a[len] -1; i >= 0, --i;) {

you want this:

for (i = len-1; i >= 0, --i;) {

but you also only want to go half-way through the array, so it would be

for (i = len-1; i > j, --i;) {
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • 1
    So i only want to go halfway through because if i went through the entire array would i just end up reversing it right back to the original positions? @Vaughn Cato – Zanderg Apr 10 '14 at 03:09
0

Try this;

#include <stdlib.h>
#include <time.h>

int Random(int Max) {
  return ( rand() % Max)+ 1;
}

void main() {
  const int len = 8;
  int a[len];
  int i,end;
  int j = 0;
  Randomize() ;

  srand(time(0));
  //Fill the Array
  for (i = 0; i < len; ++i) {
    a[i] = rand() % 100;
  }

  //Print the array after filled
  for (i = 0; i < len; ++i) {
    printf("%d ", a[i]);
  }
  printf("\n");
  getchar();

  for (i = 0; i < n/2; i++) {
      t = a[i];
      a[i]   = a[end];
      a[end] = t;
      end--;
  }

}

Hope this helps... :)

Just for suggestion. Try to use meaningful variable name instead of just i,a.... That will help you while writing a bigger code. :)

Rashad
  • 11,057
  • 4
  • 45
  • 73
  • okay so I'm running into this stupid problem now where the printf statement I'm using doesn't want to print the whole array. @Rashad – Zanderg Apr 10 '14 at 03:48
  • When i use my printf statement I'm going to be printing a[i] and a[j] together since they are both half of the array. So once i do that it's not organizing them correctly. My return array looks something like this @Rashad 80 66 36 81 44 4 43 90 //66 43 36 4 81 44 81 44 – Zanderg Apr 10 '14 at 03:59
  • @Zanderg >> Print the array after reversal. – Rashad Apr 10 '14 at 04:13
  • `t` is not defined and `end` is not initialized... printing the reversed array would help verify the operation success. – chqrlie Aug 06 '18 at 15:19
0

If you are not interested in writing functions for any numeric type, try macros for this task. This code same working with any built-in numeric type: int, float, double.

It has not a support for strings, since any string is ending on the character the NULL character \0. More a controlled version my similar answer is here https://stackoverflow.com/a/42063309/6003870 and contains solution for reverse a string.


A full code

#include <stdio.h>

// print items of an array by a format
#define PRINT_ARRAY(array, length, format) \
{ \
    putchar('['); \
    for (size_t i = 0; i < length; ++i) { \
        printf(format, array[i]); \
        if (i < length - 1) printf(", "); \
    } \
    puts("]"); \
}


// reverse an array in place
#define REVERSE_ARRAY(array, length, status) \
    if (length > 0) { \
        for (int i = 0; i < length / 2; ++i) { \
            double temp; \
            temp = array[i]; \
            array[i] = array[length - i - 1]; \
            array[length - i - 1] = temp; \
        } \
        *status = 0; \
    } \
    else if (length < 0) *status = -1; \
    else *status = 1;

#define SUCCESS_REVERSE_ARRAY_MSG "An array succefully reversed"
#define FAILED_REVERSE_ARRAY_MSG "Failed reverse for an array"
#define NO_CHANGED_REVERSE_ARRAY_MSG "An array no changed"


/*
    Print message about status reverse an array
 */
static void
print_msg_reverse_array_status(const int status)
{
    if (status == 0) printf("Status: %s\n", SUCCESS_REVERSE_ARRAY_MSG);
    else if (status == -1) printf("Status: %s\n", FAILED_REVERSE_ARRAY_MSG);
    else if (status == 1) printf("Status: %s\n", NO_CHANGED_REVERSE_ARRAY_MSG);
}


int
main (const int argc, const char *argv[])
{
    // keep value of status
    int status;

    puts("\tExample reverse of an integer array");
    int arr_int[5] = {1, 2, 3, 4, 5};

    status = 0;
    PRINT_ARRAY(arr_int, 5, "%d");
    REVERSE_ARRAY(arr_int, -1, &status);

    // will be an error, since a length is less 0, and the array is not changed
    print_msg_reverse_array_status(status);
    PRINT_ARRAY(arr_int, 5, "%d");

    status = 0;
    REVERSE_ARRAY(arr_int, 0, &status);

    // a length is equal to 0, so an array is not changed
    print_msg_reverse_array_status(status);
    PRINT_ARRAY(arr_int, 5, "%d");

    status = 0;
    REVERSE_ARRAY(arr_int, 5, &status);
    print_msg_reverse_array_status(status);
    PRINT_ARRAY(arr_int, 5, "%d");

    puts("\n\tExample reverse of an float array");
    float arr_float[5] = {0.78, 2.1, -3.1, 4, 5.012};

    status = 0;
    PRINT_ARRAY(arr_float, 5, "%5.3f");
    REVERSE_ARRAY(arr_float, 5, &status);
    print_msg_reverse_array_status(status);
    PRINT_ARRAY(arr_float, 5, "%5.3f");

    puts("\n\tExample reverse of an double array");
    double arr_double[5] = {0.00001, 20000.002, -3, 4, 5.29999999};

    status = 0;
    PRINT_ARRAY(arr_double, 5, "%8.5f");
    REVERSE_ARRAY(arr_double, 5, &status);
    print_msg_reverse_array_status(status);
    PRINT_ARRAY(arr_double, 5, "%8.5f");
    return 0;
}

I am used the GCC for compilation and your result must be as next

    Example reverse of an integer array
[1, 2, 3, 4, 5]
Status: Failed reverse for an array
[1, 2, 3, 4, 5]
Status: An array no changed
[1, 2, 3, 4, 5]
Status: An array succefully reversed
[5, 4, 3, 2, 1]

    Example reverse of an float array
[0.780, 2.100, -3.100, 4.000, 5.012]
Status: An array succefully reversed
[5.012, 4.000, -3.100, 2.100, 0.780]

    Example reverse of an double array
[ 0.00001, 20000.00200, -3.00000,  4.00000,  5.30000]
Status: An array succefully reversed
[ 5.30000,  4.00000, -3.00000, 20000.00000,  0.00000]

Testing environment

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie
$ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Chris Tang
  • 567
  • 7
  • 18
PADYMKO
  • 4,217
  • 2
  • 36
  • 41
  • If you are going to write macros, at least parenthesize the arguments in the expansion and wrap it in a `do { ... } while (0)` statement... Your code is very fragile. For example try `int temp[20], i = 20, status; REVERSE_ARRAY(temp, i, &status);` – chqrlie Aug 06 '18 at 15:11
0

You can reverse an array in place you don't need an auxiliary array for that, Here is my C code to do that

#include <stdio.h>
int main(void)
 {
    int arr[5]={1,2,3,4,5};
    int size=sizeof(arr)/sizeof(int);   
    int success= reverse(arr,size);
    if(success==1)
        printf("Array reversed properly");
    else
        printf("Array reversing failed");   

    return 0;
}


int reverse(int arr[], int size)
{
    int temp=0;
    int i=0;
    if(size==0)
        return 0;
    if(size==1)
        return 1;

    int size1=size-1;
    for( i=0;i<(size/2);i++)
    {
        temp=arr[i];
        arr[i]=arr[size1-i];
        arr[size1-i]=temp;
    }

    printf("Numbers after reversal are ");
    for(i=0;i<size;i++)
    {
        printf("%d ",arr[i]);
    }
    return 1;

}
Abhishek Nikam
  • 618
  • 7
  • 15
  • Why do you return `0` for an empty array? the reversal is trivially successful. There is really no need for these tests. – chqrlie Aug 06 '18 at 15:07
0

Here's an easy and clean function for flipping arrays of all sizes. Change the parameters according to your type of array:

void flipArray(int *a, int asize){
            int b[asize];
            int *b_p = b;

            for(int i=0; i<asize; i++){
                    //backwardsOrientation = (arraySize-1)-increment
                    b_p[asize-1-i] = a[i];
            }
            for(int i=0; i<asize; i++){
                    a[i] = b_p[i];
            }
    }
  • *function for flipping arrays of all sizes*... all small non zero sizes maybe, but large array sizes (and negative or 0 values of `asize`) will produce undefined behavior. Furthermore, there is no need for `int *b_p = b;`, just use `b` instead. – chqrlie Aug 06 '18 at 15:02
  • if you change the data type of the variables you can have arrays of all sizes. Conditionals are a bitch, I know. – Ahab Devoid Aug 07 '18 at 21:35
0
 public static void ReverseArrayInPlace()
    {
        int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        int end = arr.Length - 1;
        foreach (var item in arr)
        {
            Console.WriteLine(item);
        }

        for (int i = 0; i < arr.Length/2; i++)
        {
            var temp = arr[i];
            arr[i] = arr[end];
            arr[end] = temp;
            end--;
        }
        Console.WriteLine("--------------------------");

        foreach (var item in arr)
        {
            Console.WriteLine(item);
        }
    }
0

Here is how I did it in Java

It will be exactly same in C or C++ too

class Solution {
    private void reverseHelper(char s[],int i, int j){
        if(i >= j) return;
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
        reverseHelper(s,i+1,j-1);
    }
    
    public void reverseString(char[] s) {
        reverseHelper(s,0,s.length-1);
    }
}

The space complexity here is O(1)

KshitijV97
  • 347
  • 1
  • 4
  • 16
-1
#include<Stdio.h>
#include<string.h>
#define max 25
int main()
{ 
  char arr[max]="0123456789";
  strrev(arr);
  atoi(arr);

  return 0;
}
//you can also use built in functions such as strrev(); string reverse atoi just 
//changes string into integer
  • // you could also find sizeof(); very handy if you don't want it as a character array in the first place and any other data type – Omar M. Hussein Jan 01 '17 at 19:29
  • but if you want to make the function yourself please refer to the first comment – Omar M. Hussein Jan 01 '17 at 19:31
  • Potential undefined behavior because *C11 **7.22.1 Numeric conversion functions** The functions `atof`, `atoi`, `atol`, and `atoll` need not affect the value of the integer expression `errno` on an error. If the value of the result cannot be represented, the behavior is undefined.* – chqrlie Aug 06 '18 at 15:13