Sorting numbers in C [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have created a small C program which sorts odd and even numbers in descending order, with the user inputting whether they wish to sort the odd or the even numbers. So in order to try and make it more complex, I was wondering if there was a way in which I could have my program sort only the even numbers while leaving the odd numbers in their current place and vice versa so for instance:
Input:
odd
1 7 3 5 2 4 20
Output:
1 3 5 7 2 4 20
There is probably multiple ways to go about this, I'm wanting to include it in

First of all you should place the sort algorithm in a separate function. Secondly you can add one more parameter that will specify the predicate for elements of the array that need to be sorted.
For example
#include <stdio.h>
void sort( int a[], size_t n, int predicate( int ) )
{
for ( size_t i = 0; i < n; i++ )
{
if ( predicate( a[i] ) )
{
for ( size_t j = i + 1; j < n; j++ )
{
if ( predicate( a[j] ) && a[i] < a[j] )
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}
}
int even( int x ) { return ( x & 1 ) == 0; }
int odd( int x ) { return ( x & 1 ); }
int main(void)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
sort( a, N, even );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
sort( a, N, odd );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
return 0;
}
The program output is
0 1 2 3 4 5 6 7 8 9
8 1 6 3 4 5 2 7 0 9
8 9 6 7 4 5 2 3 0 1

Maybe something like, if the number is divisible by 2(remainder 0) it is even, so do nothing. If the number + 1 is divisible by 2(and so is odd), then sort.

... sort only the even numbers while leaving the odd numbers in their current place and vice versa
When encountering a value that matches SkipType, skip that array element.
// Return true when odd, else false
bool IsOdd(int x) {
return x%2; // x%2 --> -1,0,1
}
...
// Select skipping odd or even
bool SkipType = IsOdd(1);
for (i = 0; i < ArraySize; ++i) {
if (IsOdd(number[i]) == SkipType) continue;
for (j = i + 1; j < ArraySize /*size*/; ++j) {
if (IsOdd(number[j]) == SkipType) continue;
if (number[i] > number[j]) { // I think OP want > here, not <
a = number[i];
number[i] = number[j];
number[j] = a;
}
}
}

Related

function which arranges the elements of an array in ascending order

I try to create a function which arranges the elements of an array in ascending order. But the result isn't good. I think I have forgotten one thing... thanks for your help.
#include <stdio.h>
void ft_sort_int_tab(int *tab, int size) {
int i;
int j;
int temp;
size -= 1;
i = 0;
while (i < size) {
if (tab[i] > tab[i + 1]) {
temp = tab[i];
tab[i] = tab[i + 1];
tab[i + 1] = temp;
}
i++;
}
}
int main(void) {
int tab[9] = {9, 5, 2, 3, 8, 4, 16, 20, 24};
ft_sort_int_tab(tab, 9);
for (int i = 0; i < 9; i++) {
printf("%d ", tab[i]);
}
}
The result : 5 2 3 8 4 9 16 20 24
You've coded the inner-sweep loop of a bubblesort, but you apparently missed the point of the algorithm, as that's only half the algorithm.
Each pass of bubblesort swaps adjacent elements if they're out of order relative to each other (not the entire sequence). When a pass is finished, you're guaranteed the extreme value (largest or smallest, depending on your comparator choice) has found its home at the end of the swept partition. At that point, it should not be visited again. The next sweep run up to, but not include that element. Each sweep gets more and more elements closer to their proper homes, and at least one (the last one of that partition length) in its permanent home). As an optimization, you can track whether the current sweep every actually swapped any values.
Optionally, if the sweep completes with no swaps, you can eject entirely; the sequence is sorted. This attribute is what gives bubblesort its only redeeming quality. It is O(n) in best case, when the input sequence is already sorted when utilizing swap-detection. But it is also O(n^2) in general and worst case, making it a poor sorting choice in general.
Regardless
#include <stdio.h>
void ft_sort_int_tab(int *tab, int size)
{
while (size-- > 0) // note descending ceiling
{
int swapped = 0;
for (int i=0; i<size; ++i) // partition sweep
{
if (tab[i] > tab[i + 1])
{
int temp = tab[i];
tab[i] = tab[i + 1];
tab[i + 1] = temp;
swapped = 1;
}
}
if (!swapped) // early exit on no-swap sweep
break;
}
}
int main(void)
{
int tab[9] = {9, 5, 2, 3, 8, 4, 16, 20, 24};
ft_sort_int_tab(tab, 9);
for (int i = 0; i < 9; i++)
printf("%d ", tab[i]);
fputc('\n', stdout);
}
Output
2 3 4 5 8 9 16 20 24
It seems you are trying to implement the bubble sort algorithm.
Your function uses only one loop to move the maximum element in its target position. But you need to repeat the process for all other elements of the array.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void ft_sort_int_tab( int *tab, size_t size )
{
for ( size_t last = size; !( size < 2 ); size = last )
{
for ( size_t i = last = 1; i < size; ++i )
{
if ( tab[i] < tab[i-1] )
{
int tmp = tab[i];
tab[i] = tab[i - 1];
tab[i - 1] = tmp;
last = i;
}
}
}
}
int main(void)
{
int tab[] = { 9, 5, 2, 3, 8, 4, 16, 20, 24 };
const size_t N = sizeof( tab ) / sizeof( *tab );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", tab[i] );
}
putchar( '\n' );
ft_sort_int_tab( tab, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", tab[i] );
}
putchar( '\n' );
return 0;
}
The program output is
9 5 2 3 8 4 16 20 24
2 3 4 5 8 9 16 20 24
Pay attention to that in general the number of elements in an array should be specified by an object of the type size_t. It is the type of the value returned by the operator sizeof. An object of the type int can be not enough large to store the possible number of elements in an array.
A more general approach is to add one more parameter to the function that will specify the criteria of sorting an array. With this approach you can for example sort an array either in the ascending order or in the descending order using the same one function.
Here is a demonstrative program.
#include <stdio.h>
int ascending( int x, int y )
{
return x < y;
}
int descending( int x, int y )
{
return y < x;
}
void ft_sort_int_tab( int *tab, size_t size, int cmp( int, int ) )
{
for ( size_t last = size; !( size < 2 ); size = last )
{
for ( size_t i = last = 1; i < size; ++i )
{
if ( cmp( tab[i], tab[i-1] ) )
{
int tmp = tab[i];
tab[i] = tab[i - 1];
tab[i - 1] = tmp;
last = i;
}
}
}
}
int main(void)
{
int tab[] = { 9, 5, 2, 3, 8, 4, 16, 20, 24 };
const size_t N = sizeof( tab ) / sizeof( *tab );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", tab[i] );
}
putchar( '\n' );
ft_sort_int_tab( tab, N, ascending );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", tab[i] );
}
putchar( '\n' );
ft_sort_int_tab( tab, N, descending );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", tab[i] );
}
putchar( '\n' );
return 0;
}
The program output is
9 5 2 3 8 4 16 20 24
2 3 4 5 8 9 16 20 24
24 20 16 9 8 5 4 3 2
Your code swaps the two elements if needed, but then moves on to the next position in the array. In the beginning of your example, the 9 and 5 get swapped, so 5 ends up in the first position, but 5 never gets compared to other elements.
There are lots of sorting algorithms out there, and you should read about them. The one that your code seems most similar to is called “bubble sort.” To get there, modify your code do that it makes multiple passes over the array until the array is completely sorted. If you made a second pass, for example, the 5 and 2 would get swapped, and you’d be closer to a sorted result.
Bubble sort is not the fastest way to sort, but it’s easy to understand. Other ways include quicksort, mergesort, and heapsort. Wikipedia can explain each of those, and they’re worth looking into if your need better performance.

duplicate same following elements in array

I should build a function that gets an array and it's size and return a pointer
to new array (i need do create new array by using malloc and realloc) that find the identical numbers and duplicates them in the row
for example the array:{1,8,8,70,2,2,2,5,5,2} and size 10 suppose to return a pointer to this array
{1,8,8,8,8,70,2,2,2,2,2,2,5,5,5,5,2}. Any clue what's wrong with my code??
int * duplicateArray(int* arr, int n)
{
int g = 1;
int i,j=0;
int *p = (int*)(calloc)(n, sizeof(int));
assert(p);
for (i = 0; i < n-1; i++)
{
if (arr[i] == arr[i + 1])
{
p= (int*)(realloc)(p, n+g * sizeof(int));
n=n+g;
assert(p);
p[j] = arr[i];
j++;
p[j] = arr[i+1];
}
else
p[j] = arr[i];
j++;
}
return p;
}
The approach used by you when the memory is constantly reallocated is inefficient.
Also the function should return not only the pointer to the dynamically allocated array but also the number of elements in the allocated array. Otherwise the user of the function will not know how many elements are in the allocated array. To use a sentinel value for an integer dynamically allocated array is not a good idea.
I suggest to split the task into two separate tasks that will correspond to two separate functions..
The first function will count the number of repeated elements in a given array.
The second function will create dynamically an array with the specified size based on the returned value of the first function and copy elements of the source array to the newly created array.
Here is a demonstrative program
#include <stdio.h>
#include <stdlib.h>
size_t countRepeated( const int a[], size_t n )
{
size_t repeated = 0;
for ( size_t i = 0; i != n; )
{
size_t m = 1;
while ( ++i != n && a[i] == a[i-1] ) ++m;
if ( m != 1 ) repeated += m;
}
return repeated;
}
int * copyWithDuplication( const int a[], size_t n, size_t m )
{
int *result = m == 0 ? NULL : calloc( m, sizeof( int ) );
if ( result )
{
for ( size_t i = 0, j = 0; j != m && i != n; )
{
result[j++] = a[i++];
size_t k = 1;
while ( j != m && i != n && a[i] == a[i-1] )
{
result[j++] = a[i++];
++k;
}
if ( k != 1 )
{
while ( j != m && k-- ) result[j++] = a[i-1];
}
}
}
return result;
}
int main(void)
{
int a[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
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 = N + countRepeated( a, N );
int *b = copyWithDuplication( a, N, m );
if ( b )
{
for ( size_t i = 0; i < m; i++ )
{
printf( "%d ", b[i] );
}
putchar( '\n' );
}
free( b );
return 0;
}
The program output is
1 8 8 70 2 2 2 5 5 2
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5 2
And here is another more interesting demonstrative program.
#include <stdio.h>
#include <stdlib.h>
size_t countRepeated( const int a[], size_t n )
{
size_t repeated = 0;
for ( size_t i = 0; i != n; )
{
size_t m = 1;
while ( ++i != n && a[i] == a[i-1] ) ++m;
if ( m != 1 ) repeated += m;
}
return repeated;
}
int * copyWithDuplication( const int a[], size_t n, size_t m )
{
int *result = m == 0 ? NULL : calloc( m, sizeof( int ) );
if ( result )
{
for ( size_t i = 0, j = 0; j != m && i != n; )
{
result[j++] = a[i++];
size_t k = 1;
while ( j != m && i != n && a[i] == a[i-1] )
{
result[j++] = a[i++];
++k;
}
if ( k != 1 )
{
while ( j != m && k-- ) result[j++] = a[i-1];
}
}
}
return result;
}
int main(void)
{
int a[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
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 = N + countRepeated( a, N );
for ( size_t i = 0; i < m; i++ )
{
int *b = copyWithDuplication( a, N, i + 1 );
if ( b )
{
for ( size_t j = 0; j < i + 1; j++ )
{
printf( "%d ", b[j] );
}
putchar( '\n' );
}
free( b );
}
return 0;
}
Its output is
1 8 8 70 2 2 2 5 5 2
1
1 8
1 8 8
1 8 8 8
1 8 8 8 8
1 8 8 8 8 70
1 8 8 8 8 70 2
1 8 8 8 8 70 2 2
1 8 8 8 8 70 2 2 2
1 8 8 8 8 70 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2 2
1 8 8 8 8 70 2 2 2 2 2 2 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5
1 8 8 8 8 70 2 2 2 2 2 2 5 5 5 5 2
Any clue what's wrong with my code??
If the parameter n is 1, then your program will allocate an array for 1 element of type int, but will write nothing to it. It won't copy anything from the input buffer.
You are accessing both the input arr and the output array p out of bounds, which causes undefined behavior. The loop
for (i = 0; i < n-1; i++)
will not count from 0 to the function parameter n minus 2, because n is being incremented inside the loop. This causes your loop to have more iterations than it is supposed to, which causes both the input and the output array to be accessed out of bounds.
Also, there doesn't seem to be much point in your variable g, as it never changes and always has the value 1.
The function prototype
int * duplicateArray(int* arr, int n);
does not seem meaningful, as the calling function has no way of knowing the size of the returned array. If you use the function prototype
void duplicateArray ( const int *p_input_array, int num_input, int **pp_output_array, int *p_num_output );
instead, the function duplicateArray can write the address of the new array to *pp_output_array and the number of elements in the array to *p_num_output. That way, the calling function will effectively be able to receive two "return values" instead of only one.
Here is my implementation of the function duplicateArray and also of the calling function:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void duplicateArray( const int *p_input_array, int num_input, int **pp_output_array, int *p_num_output )
{
int i = 0, j = 0;
// In the most extreme case, the output array must be 2 times larger than
// the input buffer, so we allocate double the size of the input buffer.
int *p_output_array = (int*)malloc( num_input * 2 * sizeof(int) );
assert( p_output_array != NULL );
while ( i < num_input )
{
int num_repetitions;
int k = p_input_array[i++];
//count the number of repetitions
for ( num_repetitions = 0; i < num_input && p_input_array[i] == k; num_repetitions++, i++ );
if ( num_repetitions == 0 )
{
p_output_array[j++] = k;
}
else
{
for ( int l = 0; l < num_repetitions + 1; l++ )
{
p_output_array[j++] = k;
p_output_array[j++] = k;
}
}
}
//shrink the array to the actually needed size
p_output_array = (int*)realloc( p_output_array, j * sizeof(int) );
assert( p_output_array != NULL );
*pp_output_array = p_output_array;
*p_num_output = j;
}
int main()
{
int arr[] = { 1, 8, 8, 70, 2, 2, 2, 5, 5, 2 };
int *p;
int num;
duplicateArray( arr, sizeof(arr)/sizeof(*arr), &p, &num );
for ( int i = 0; i < num; i++ ) {
printf( "%d\n", p[i] );
}
free( p );
}

i want to add a constant to an array of numbers but differently in C

for example i have an array with elements
0 1 2 3 4 5 6
i want to add say 3 to all the elements and want this output:
3 4 5 6 0 1 2 after the addition the numbers should not exceed the largest element, but start from the smallest one.
Hard to explain.
Is there some way of doing this in c? (not c++)
What you are describing seems to be addition modulo the maximum element + 1, i.e., a sum greater than the maximum element wraps around.
Find the maximum element, let's call it max, by iterating over the array.
Iterate over the array again, and for each element do the addition modulo max + 1, i.e., conceptually arr[i] = (arr[i] + n) % (max + 1).
(If it was intended that the wrap-around is not to zero but to the minimum element, then also find the smallest value in step 1 and do arr[i] = ((arr[i] - min + n) % ((max - min) + 1)) + min in step 2.)
If I have understood correctly you need something like the following.
#include <stdio.h>
size_t max_element( const int a[], size_t n )
{
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] ) max = i;
}
return max;
}
int main(void)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6 };
const size_t N = sizeof( a ) / sizeof( *a );
int value = 0;
printf( "Enter a value to add to elements of the array: " );
scanf( "%d", &value );
size_t max = max_element( a, N );
int upper_value = a[max] + 1;
for ( size_t i = 0; i < N; i++ )
{
a[i] = ( a[i] + value ) % upper_value;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output might look like
Enter a value to add to elements of the array: 3
3 4 5 6 0 1 2

What parameters to set as main loop

Okay, so I have a homework question, which goes as follows: From the array make pairs (b, c) where b is lowest even number, and c is biggest. Write numbers in output, remove them from the array and continue the loop until there are no more even numbers, or the array is empty.
EDIT: If there is only 1 even number, output it as the biggest and lowest number at the same time, so that the final array has no even numbers.
Here is what I did for now:
int a[100], b, c, n;
b = 9999999;
c = -9999999;
printf("Input array length: ");
scanf("%d", &n);
printf("Input elements of array: ");
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < n; i++) {
if (a[i] < b && a[i] % 2 == 0)
b = a[i];
}
for (int i = 0; i < n; i++) {
if (a[i] > c && a[i] % 2 == 0)
c = a[i];
}
printf("\n%d %d\n", b, c);
return 0;
I set absurd values for b and c on start so that I 99% sure there will be numbers from the array that is lower/higher from those values (I tried to set them as NULL but that didn't). So my question is how to set the main loop that will circle until there are no even numbers or array is empty? Also is there another way I can initialize b and c.
Also, for removing even numbers, I was thinking about doing something like this:
for (int i = pos; i < n; i++)
a[i] = a[i+1];
n--;
Where pos is an index of the even element.
You can not resize an array but you can track its size of actual elements.
I suppose that if in the array there is only one even element then there is no pair of the minimum and maximum even elements in the array. So in this case nothing is "removed" from the array and the process stops. However you can change the approach and "remove" even a single even element.
And the request of the assignment to remove elements means that the order of the elements in the array must be kept. You may not sort the array.
That is when you are asked to remove an element from an array then this does not mean that you are to sort the array.:)
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
struct Pair
{
size_t min;
size_t max;
};
struct Pair minmax_element( const int a[], size_t n )
{
struct Pair p = { n, n };
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 == 0 )
{
if ( p.min == n || a[i] < a[p.min] ) p.min = i;
if ( p.max == n || a[p.max] < a[i] ) p.max = i;
}
}
return p;
}
int main(void)
{
enum { N = 20 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int success = 1;
size_t n = N;
while ( success )
{
struct Pair p = minmax_element( a, n );
success = p.min != n && p.max != n;
if ( success )
{
printf( "minimum even number = %d, maximum even number = %d\n",
a[p.min], a[p.max] );
if ( p.max < p.min )
{
size_t tmp = p.min;
p.min = p.max;
p.max = tmp;
}
memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
--n;
memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
--n;
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
Its output might look like
8 3 6 16 3 4 9 8 1 4 15 9 16 12 3 7 10 19 15 15
minimum even number = 4, maximum even number = 16
minimum even number = 4, maximum even number = 16
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
3 3 9 8 1 15 9 3 7 19 15 15
As it is seen in the result array there is one even element with the value 8 because the array does not have any more even element to make a pair.
Edit: Taking into account your comment
Oh sorry, I forgot to mention that if there is only 1 element (in this
example 8), you simply output it 2 times at the and, as the lowest and
biggest number, so that the final output has no even numbers.
the demonstrative program can look the following way
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
struct Pair
{
size_t min;
size_t max;
};
struct Pair minmax_element( const int a[], size_t n )
{
struct Pair p = { n, n };
for ( size_t i = 0; i < n; i++ )
{
if ( a[i] % 2 == 0 )
{
if ( p.min == n || a[i] < a[p.min] ) p.min = i;
if ( p.max == n || a[p.max] < a[i] ) p.max = i;
}
}
return p;
}
int main(void)
{
enum { N = 20 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int success = 1;
size_t n = N;
while ( success )
{
struct Pair p = minmax_element( a, n );
success = p.min != n;
if ( success )
{
if ( p.max == n ) p.max = p.min;
printf( "minimum even number = %d, maximum even number = %d\n",
a[p.min], a[p.max] );
if ( p.max < p.min )
{
size_t tmp = p.min;
p.min = p.max;
p.max = tmp;
}
memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
--n;
if ( p.min != p.max )
{
memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
-- n;
}
}
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
Its output might look like
3 10 0 12 16 0 13 11 15 16 6 8 11 10 11 12 4 14 4 3
minimum even number = 0, maximum even number = 16
minimum even number = 0, maximum even number = 16
minimum even number = 4, maximum even number = 14
minimum even number = 4, maximum even number = 12
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
minimum even number = 10, maximum even number = 10
3 13 11 15 11 11 3
So, this problem is much much easier if you simply sort the array.
I would replace your current for loops with the following logic:
1) Sort the array from lowest to highest.
2) Increment through the array from both ends and pop out the highest and lowest values if and only if they are even.
3) Eventually your increments will meet in the middle and the loop can end when the two counters meet.
This is just a simple sort followed by a one for loop. Once they are popped you can set the values you popped to 0.
You need to set up an encompassing while loop that continues running so long as there are even elements in the array. You can break from this loop if you find no even elements in your iteration. Also it seems at the moment you haven't implemented deletion from the array; this can be done in several ways, but in my opinion the easiest is just to maintain a second "checked" array that stores 1's or 0's to signify if an element has been previously taken. As follows:
int seen[n];
for (int i = 0; i < n; i++){
seen[i] = 0;
}
while (1){
int flag = 0, ind1 = 0, ind2 = 0;
b = 0;
c = 0;
for (int i = 0; i < n; i++) {
if ((!flag || a[i] < b) && a[i] % 2 == 0 && !seen[i]){
flag = 1;
b = a[i];
ind1 = i;
}
}
flag = 0;
for (int i = 0; i < n; i++) {
if ((!flag || a[i] > c) && a[i] % 2 == 0 && !seen[i] && i != ind1){
flag = 1;
c = a[i];
ind2 = i;
}
}
if (!flag){
printf("No more even elements (or only one remaining) in the array.\n");
break;
}
seen[ind1] = 1;
seen[ind2] = 1; // "removing" them from the array
printf("\n%d %d\n", b, c);
}
Flag is set to 0 at the end of the second for loop if it's unable to find an even number that has yet to be taken, and breaks upon this condition.
This also solves the problem of initializing b and c. Your current approach to that is probably fine in most cases, but in this solution you simply set them to the first even value you find in the array (that hasn't been previously taken), since the minimum will be less than or equal to it, and the maximum greater than or equal to it.
As a side note, another (easier) way to "remove values" is to set them to odd numbers, since then you'll just pass over them in iteration. I decided not to go with this approach in interests of preserving the initial array, if it's what your teacher prefers.
The least I can think of is you can use a trick (not all teachers allow this, because it is kinda nonsense and considered as not doing the homework).
Make a variable odd[n] (not recommended), if you are worried about the memory used, you can simply do a for loop from 0 to n-1 to find how many odd numbers so you can make it like odd[n_odd].
Then you do a for loop from 0 to n-1, if the number is odd, assign it to odd[]. So you just need to print just the odd numbers. If it's necessary to find max & min even numbers and delete the pairs, you can ignore my comment (This is an idea instead of an answer). Otherwise, Vlad's answer is the correct one.

i cant get bubble sorting to work in function while passing array to the function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
#include <stdio.h>
#include <conio.h>
void ascending(int numbers[], int size);
int main()
{
int size=10, numbers[size], i, order;
for (i=0; i<10; i++)
{
printf("please enter a number:");
scanf("%d", &numbers[i]);
}
ascending(numbers[], size);
}
void ascending(int numbers[], int size)
{
int temp, i, sflag, count=0;
do
{
sflag = 0;
for(i=1; i <10; i++)
{
if (numbers[i-1] > numbers[i])
{
temp = numbers[i-1];
numbers[i-1] = numbers[i];
unmbers[i] = temp;
sflag = 1;
}
}
count++;
}while(sflag);
for (i=0; i<10; i++)
{
printf("%d\t", numbers[i]);
}
}
the code fails at the the first if statement in the function, it says segmentation error.
im not sure why, i think there may be an error in how i am passing the array to the function.
There are at least two typos in your program.
The first one is in this statement
ascending(numbers[], size);
^^^
There should be
ascending(numbers, size);
The second one in this statement
unmbers[i] = temp;
^^^^^^^^
There should be
numbers[i] = temp;
Also in this statement within the function
for(i=1; i <10; i++)
you are using a magic number 10 instead of the variable size.
Nevertheless your function is inefficient because the inner loop always iterate from 1 to size.
A more efficient its implementation can look as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bubble_sort( int a[], size_t n )
{
for ( size_t last = n; !( n < 2 ); n = last )
{
last = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[i] < a[i-1] )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
}
}
int main(void)
{
enum { N = 10 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
bubble_sort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
putchar( '\n' );
}
return 0;
}
In the program an array of random numbers is sorted 10 times.
The program output might look for example like.
4 0 1 0 5 7 1 1 5 2
0 0 1 1 1 2 4 5 5 7
8 1 1 0 7 1 3 1 1 0
0 0 1 1 1 1 1 3 7 8
6 0 8 2 8 3 7 4 7 8
0 2 3 4 6 7 7 8 8 8
2 1 0 3 4 5 3 7 8 0
0 0 1 2 3 3 4 5 7 8
9 6 3 0 9 0 4 4 4 5
0 0 3 4 4 4 5 6 9 9
5 2 7 5 4 7 0 1 2 7
0 1 2 2 4 5 5 7 7 7
1 4 1 4 9 5 1 4 4 0
0 1 1 1 4 4 4 4 5 9
6 5 8 0 7 9 2 1 4 6
0 1 2 4 5 6 6 7 8 9
9 1 9 6 6 5 4 8 9 8
1 4 5 6 6 8 8 9 9 9
5 2 4 6 6 5 3 0 2 7
0 2 2 3 4 5 5 6 6 7
If you are going to use the same sorting function to sort an array in ascending and descending orders then the function can look as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void bubble_sort( int a[], size_t n, int cmp( int, int ) )
{
for ( size_t last = n; !( n < 2 ); n = last )
{
last = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( cmp( a[i], a[i-1] ) )
{
int tmp = a[i];
a[i] = a[i-1];
a[i-1] = tmp;
last = i;
}
}
}
}
int ascending( int x, int y )
{
return x < y;
}
int descending( int x, int y )
{
return y < x;
}
int main(void)
{
enum { N = 10 };
int a[N];
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
a[i] = rand() % N;
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
bubble_sort( a, N, ascending );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
bubble_sort( a, N, descending );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output might look like
9 0 1 6 0 8 7 4 9 4
0 0 1 4 4 6 7 8 9 9
9 9 8 7 6 4 4 1 0 0
/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio.h>
#include <stdio.h>
#include <conio.h>
void ascending(int numbers[], int size);
int main()
{
int size=10, numbers[size], i, order;
for (i=0; i<10; i++)
{
printf("please enter a number:");
scanf("%d", &numbers[i]);
}
ascending(numbers, size);
return 0;
}
void ascending(int numbers[], int size)
{
int temp, i, sflag, count=0;
do
{
sflag = 0;
for(i=1; i <10; i++)
{
if (numbers[i-1] > numbers[i])
{
temp = numbers[i-1];
numbers[i-1] = numbers[i];
numbers[i] = temp;
sflag = 1;
}
}
count++;
}while(sflag);
for (i=0; i<10; i++)
{
printf("%d\t", numbers[i]);
}
}
Running your code slightly modified (make it compile able) in https://www.onlinegdb.com/online_c_compiler#
I was not able to detect any error
I checkt 3,7,8,8,9,10,11,200,317 and 1,1,1,1,1,1,1,1,1
There are 2 mistakes in your code:
on line 13 you are passing numbers[] to the ascending function. This is wrong, you can never pass anything with [], when you call a function. When you write int numbers[] in the argument list of a function, it means that you want the function to accept a pointer to a number, you are just declaring this to the compiler. So it should just be ascending(numbers, size);
on line 30 you made a typo, you wrote unmbers[i] = temp;, while it should be numbers[i] = temp;
here is the correct code:
#include <stdio.h>
#include <conio.h>
void ascending(int numbers[], int size);
int main()
{
int size=10, numbers[size], i, order;
for (i=0; i<10; i++)
{
printf("please enter a number:");
scanf("%d", &numbers[i]);
}
ascending(numbers, size);
}
void ascending(int numbers[], int size)
{
int temp, i, sflag, count=0;
do
{
sflag = 0;
for(i=1; i <10; i++)
{
if (numbers[i-1] > numbers[i])
{
temp = numbers[i-1];
numbers[i-1] = numbers[i];
numbers[i] = temp;
sflag = 1;
}
}
count++;
}while(sflag);
for (i=0; i<10; i++)
{
printf("%d\t", numbers[i]);
}
}

Resources