Reverse an integer array in C [duplicate] - c

This question already has answers here:
Reverse an array in c
(3 answers)
Closed 5 years ago.
Given an integer array with 5 elements [1,2,3,4,5], I am attempting to reverse the order of the elements in the array; e.g. the array would become [5,4,3,2,1].
int main(void) {
int n = 5; //Num of elements
int arr[5] = {1,2,3,4,5};
for (int i = 0; i < n; i++) {
printf("%d\n", arr[i]); //Print original vals
}
n--; //Decrement n by 1 for simplicity
for (int i = n; i >= 0; i--) {
int temp = arr[n - i]; //Set temp the max-index (4) - i
printf("\nSmall: %d\nBig: %d\n", arr[n - i], arr[i]); //Print current temp & arr[i]
arr[n - i] = arr[i]; //Set arr[max-index - i] to arr[i] (e.g arr[0] = arr[4])
arr[i] = temp; //Set arr[i] to arr[max-index - 1] (e.g. arr[4] = arr[0])
printf("\nBig: %d\nSmall: %d\n", arr[n - i], arr[i]); //Print new set
}
for (int i = 0; i < n + 1; i++) { //Print array in reverse order
printf("%d\n", arr[i]);
}
return 0;
}
The first for loop should print:1 2 3 4 5
and the last: 5 4 3 2 1
However, it prints 1 2 3 4 5 both times, but the print statements in the loop that reverses the array prints the right numbers.
Have I done something wrong?
Should I be dynamically allocating memory or something else not allowing me to change the array?

The problem is, you swap every element twice (unless it is the center one) which ultimately does not swap anything. At the first loop, you technically swap first and last item. At the last loop, you did the same. So, you reverse the first action, returning the item back to original position.
Another problem is you try to access arr[5] which is undefined as your array is of size 5 and thus the index should be from 0 to 4 only.
Following is a function reversing the array:
void ReverseArray(int arr[], int size)
{
for (int i = 0; i < size/2; i++)
{
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}

To reverse an array you have to do as follows:
for(int i = i; i<n/2; ++i)
{
int temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}

You are reversing the array twice.
On each iteration you swap two numbers to the same distance from the center.
So, on the first half of the iterations you have already reversed the array. As you keep iterating you swap again and the array stays unmodified.
To fix it just change the reversing loop to this (change i>=n for i>=n/2 )
for (int i = n; i >= n/2; i--) {...swaping operations...}

Related

C language: When [variables++] in array[ ] work? For example, when array[j++] = arr[i]. It is doing j++ first or do = arr[i] first?

disclaimer this is not my code and this code is from Remove Duplicate Elements from an Array in C - Javatpoint
What I want to know is in the Example 2 coding part. (I edit code a bit for me or you can see the code clearly.)
/* program to delete the duplicate elements from sorted array in C. */
#include <stdio.h>
int duplicate_element ( int arr[], int num)
{
// check num is equal to 0 and num == 1
if (num == 0 || num == 1)
{
return num;
}
// create temp array to store same number
int temp [num];
// declare variable
int i, j = 0;
// use for loop to check duplicate element
for (i = 0; i < num - 1; i++)
{
// check the element of i is not equal to (i + 1) next element
if (arr [i] != arr[i + 1])
{
temp[j++] = arr[i];
}
}
temp[j++] = arr[ num - 1];
// check the original array's elements with temporary array's elements
for (i = 0; i < j; i++)
{
arr[i] = temp[i];
}
return j;
}
int main ()
{
int num;
printf (" Define the no. of elements of the array: ");
scanf (" %d", &num);
int arr[num], i;
printf (" Enter the elements: ");
// use loop to read elements one by one
for ( i = 0; i < num; i++)
{
scanf (" %d", &arr[i]);
}
printf (" \n Elements before removing duplicates: ");
for ( i = 0; i < num; i++)
{
printf (" %d", arr[i]);
}
num = duplicate_element (arr, num);
// print array after removing duplicates elements
printf (" \n Display array's elements after removing duplicates: ");
for ( i = 0; i < num; i++)
{
printf (" %d", arr[i]);
}
return 0;
}
Here's the question, what does all j++ in function duplicate_element do? (If possible I would like to know what the code is doing since line // use for loop to check duplicate element until before return too. This part I'm just curious if I know it correctly or not.)
This is my understanding (j is the final size of arr[]). In the first question, when executed
j right now is 0
temp[j++]
is it plus the value of j by 1 first then assign value arr[i] to temp[1]. (Does this right?)
The second question, in the first for loop checks when the value in arr[i] is not equal to the value in arr[i + 1] then assign value in temp[j++] with value in arr[i] until for loop is over then assign temp[j++] with arr[num - 1]
(j++ right now is dependent on the if condition for example when all value is not equal to the value of j++ == value of num - 1 and num - 1 is equal to the last value of arr)
and in the last for loop, it assigns every value in Array arr with Array temp. (Does this right?)
In short, the statement
temp[j++] = arr[i];
is equivalent to
int old_value_of_j = j;
j = j + 1;
temp[old_value_of_j] = arr[i];
For starters the code is very bad.
Firstly, the function should be declared like
size_t duplicate_element ( int arr[], size_t num );
That is the size of the passed array should be specified using the unsigned integer type size_t instead of the signed int type int. Otherwise this declaration of the variable length array
// create temp array to store same number
int temp [num];
along with this statement
temp[j++] = arr[ num - 1];
will invoke undefined behavior if the user will pass as the second argument a negative number and according to the function specification it allows to pass a negative number.
Secondly, using the variable length array temp
// create temp array to store same number
int temp [num];
makes the function unsafe. It can occur such a way that the program will be unable to define this variable length array.
The approach is too complicated, confusing and inefficient.
As for your question relative to the postfix operator ++ then according to the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the operand.
As a side effect, the value of the operand object is incremented (that
is, the value 1 of the appropriate type is added to it).
So in fact this statement
temp[j++] = arr[i];
may be equivalently rewritten like
temp[j] = arr[i];
j += 1;
As the function adds to the array temp the last element in a series of duplicated elements in the array arr then after this main loop
// use for loop to check duplicate element
for (i = 0; i < num - 1; i++)
{
// check the element of i is not equal to (i + 1) next element
if (arr [i] != arr[i + 1])
{
temp[j++] = arr[i];
}
}
you need to add the last element pf the array arr to the array temp
temp[j++] = arr[ num - 1];
Here is a demonstration program that shows how the function can be rewritten and can look more simpler.
#include <stdio.h>
size_t duplicate_element( int a[], size_t n )
{
size_t m = 0;
for (size_t i = 0; i < n; i++)
{
if (i == 0 || a[i] != a[m-1])
{
if (i != m) a[m] = a[i];
++m;
}
}
return m;
}
int main( void )
{
int a[] = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
size_t m = duplicate_element( a, N );
for (size_t i = 0; i < m; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
1 2 2 3 3 3 4 4 4 4 5 5 5 5
1 2 3 4 5

Moving the elements of an array

I'm trying to make a program that moves the elements of an array from right to left and then prints them, but the only thing that the program prints is the last value: why?
int main (){
int n = 5;
int array[n];
int i = 0;
int temp = 0;
while (i < n) {
printf("Insert the values\n");
scanf("%d", &array[i]);
i++;
}
i = 0;
temp = array[i];
i = n-1;
while (i > 0) {
i--;
array[i] = array[i+1];
}
i = 0;
while (i < n) {
printf("%d\n", array[i]);
i++;
}
return 0;
}
Example of input and expected output:
Input: 1,2,3,4,5
Output: 2,3,4,5,1
In the loop
i = n-1;
while (i > 0) {
i--;
array[i] = array[i+1];
}
The value of the last element is written to the second last element, and after that the value of the second last element (now the value of the last element) is written to the third last element. The other elements will also get the value of the last element like this.
The order of process should be reversed like this:
i = 0;
while (i+1 < n) {
array[i] = array[i+1];
i++;
}
Step through your code. You start off with the last element, and copy it to the second to the last element. Say the elements are {1, 2, 3, 4, 5}. This means that array[3] before you enter the loop is 4, but after the first iteration, is 5 (array[i] (4)] = array[i+1 (5)] (5)). Then you move down to array[2], and set it to array[3], which is now five. This repeats for the whole array, until all elements contain 5 (the last value). By the way you aren't even using temp, did you intend to do something with it and forget?
You have to preserve the first element of the array (array [0]) in a temp variable then shift the array elements from 0 to n-2, then you will have to insert the first element (array [0]) at the index of last element array [n-1]
#include <stdio.h>
#include <stdlib.h>
int main (){
int n = 5;
int array[n];
int i = 0;
while (i < n) {
printf("Insert the value :");
scanf("%d", &array[i]);
i++;
}
int temp = array[0];
i = 0;
while (i < n-1) {
array[i] = array[i+1];
i++;
}
array[n-1]=temp;
printf("\n\n");
i = 0;
while (i < n) {
printf("%d\n", array[i]);
i++;
}
return 0;
}
When you want to move elements to the left, you must first put i in the temporary variable because the value of this variable must remain to move to the previous elements.
i = n-1;
while (i >1) {
temp = array[i-1];
array[i-2] = temp;
array[i-1] = array[i];
i--;
}

Is it the efficeint program to rotate array in left direction?

#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.

Trying to implement a simple bubble sort function on a list of self declared arrays

Newbie trying to make an arrays then sort them using a function called "sort" that i created at the bottom of the code, using bubble sort..
I'm pretty sure the printing part is ok, just the functions that I'm having trouble with, can someone help a newbie out please?..
#include <stdio.h>
#include <cs50.h>
void sort(int arrayRack[], int NumberOfArrayElements);
int main(void)
{
//variable declarations
int NumberOfArrayElements = 0;
//Get number of arrays
printf("number of arrays you'd like?\n");
NumberOfArrayElements = GetInt();
//variable array declaration
int arrayRack[NumberOfArrayElements];
//Get number for each int
for(int i = 0; i < NumberOfArrayElements; i++)
{
printf("give me an int for the %i th array\n", i + 1);
arrayRack[i] = GetInt();
}
//print what is currently in the arrayRack
for(int j = 0; j < NumberOfArrayElements; j++)
printf("{%i}<-- number in %i-th array (unsorted)\n", arrayRack[j], j + 1);
for(int i = 0; i < NumberOfArrayElements; i++)
{
sort(&arrayRack[i], NumberOfArrayElements);
printf("{%i}<-- number in %i-th array (sorted)\n", arrayRack[i], i + 1);
}
return 0;
}
//this is the funciton, like sort(haystack, size);
void sort(int arrayRack[], int NumberOfArrayElements)
{
//declare variable
int swap = 0;
for(int k = 0; k < NumberOfArrayElements; k++)
{
//if [1] is higher, swap with [2]
if(arrayRack[k] > arrayRack[k + 1])
{
swap = arrayRack[k];
arrayRack[k] = arrayRack[k + 1];
arrayRack[k + 1] = swap;
}
}
}
You pass a pointer to element &arrayRack[i] but in the parameters of sort you have declared the first parameter to be an array so this doesn't match. You could simply write:
In main:
sort(arrayRack, NumberOfArrayElements);
for(int i = 0; i < NumberOfArrayElements; i++)
{
printf("{%i}<-- number in %i-th array (sorted)\n", arrayRack[i], i + 1);
}
And in sort function:
void sort(int arrayRack[], int NumberOfArrayElements)
{
//declare variable
int swap = 0;
for(int k = 0; k < NumberOfArrayElements-1; k++)
{
for(int j=0; j<NumberOfArrayElements-1-k;j++)
if(arrayRack[j] > arrayRack[j + 1])
{
swap = arrayRack[j];
arrayRack[j] = arrayRack[j + 1];
arrayRack[j + 1] = swap;
}
}
}
Also I would suggest scanf("%d",&NumberOfArrayElements); instead of NumberOfArrayElements = GetInt(); and scanf("%d",&arrayRack[i]); instead of arrayRack[i] = GetInt();
Example:
number of arrays you'd like?
5
give me an int for the 1 th array
5
give me an int for the 2 th array
7
give me an int for the 3 th array
1
give me an int for the 4 th array
8
give me an int for the 5 th array
3
{5}<-- number in 1-th array (unsorted)
{7}<-- number in 2-th array (unsorted)
{1}<-- number in 3-th array (unsorted)
{8}<-- number in 4-th array (unsorted)
{3}<-- number in 5-th array (unsorted)
{1}<-- number in 1-th array (sorted)
{3}<-- number in 2-th array (sorted)
{5}<-- number in 3-th array (sorted)
{7}<-- number in 4-th array (sorted)
{8}<-- number in 5-th array (sorted)

Optimise a code of random number with no repetition in C

I do a code that will display to the screen 10 random numbers with no repetitions. I want to know if we can optimize the code or if you have a better and simple way in order to do this request.
Thanks !!
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
for (i = 0; i < 10; i++)
{
do
{
nbr = rand() % 10 + 1;
flag = 1;
for (j = 0; j < i; j ++)
{
if (nbr == arr[j])
{
flag = 0;
break;
}
}
} while (!flag);
arr[i] = nbr;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
system("PAUSE");
return 0;
}
So if i get what you're trying to do here it is:
generate an array of numbers between 1 and 10, in a random order (given rand() % 10 + 1)
instead of trial and error I'd suggest the following algorithm:
fill arr with 1...10
shuffle arr
this will run a lot faster
While I agree with the solution provided by Work of Artiz, this will result in the hard question to answer of when to stop shuffling.
To solve this you can use the following solution (which will use more memory, but less clock time):
1 Create an array temp having values 1..10 (ordered, not random)
2 Keep track of the length length of the array (10)
3 Generate a random index rand_i between 0 and length - 1
4 Copy temp[rand_i] to next position in your final array
5 Overwrite temp[rand_i] by temp[length-1]
6 Decrement length
7 Iterate Steps 3 - 6 until your array is filled (10 times)
This will both eliminate your excessive looping, and the problem of when to stop shuffling your array
EDIT: including code
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
int temp[10] = {1,2,3,4,5,6,7,8,9,10};
int length = 10;
for (i = 0; i < 10; i++)
{
nbr = rand() % length; // Generate random index between 0 and length - 1
arr[i] = temp[nbr]; // Copy value from random index in temp to next index in arr
// Now since temp[nbr] is already taken (copied to arr) we should replace it by last available value in temp (temp[lenght])
// and in the next iteration we will create a value between 0 and length -1. This will keep values not yet taken from temp in
// contiguous order
temp[nbr] = temp[length-1];
length--;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
return 0;
}

Resources