C kind of sorting - c

Ok so a function which arranges the elements in an array in such a way that all elements
smaller than a given value are placed into positions to the left of the elements that are larger
than the given value.
For instance if the array contents are {4,6,2,9,1,7,3,10} and x is given as 5, then
{4,3,2,1,9,7,6,10} is a possible solution, since all elements smaller than 5 are to the left
of the elements larger than 5.
Also, using brackets [ ] is ​ forbidden ​ except for defining the array in the main function.
Also, implement a function which prints the contents of an array. Both functions must be
implemented recursively.
you are allowed to access each element of the array only for once.
ok so this "challenge" and I dont know if it is possible with the given restrictions. I have tried to make it with a while loop and then convert it to recursive somehow but you are not allowed to change the parameters as well. Does anyone know a solution.
I have written something but its garbage.
#include <stdio.h>
#define length 8
void selection(int array[],int size, int x){
int i=0;
int temp;
if(( array[i]>x ) && (array[i] > array[i+1])){
temp=array[i+1];
array[i+1]=array[i];
array[i]=temp;
i++;
selection(array+1,size-1,x)
}
else if(( array[i] > x) && ( array[i+1] > array[i])){
i++;
}
//This is not correct
}
void printArray(int arr[], int start, int len)
{
if(start >= len)
return;
printf("%d ", arr[start]);
printArray(arr, start + 1, len);
}
int main(){
int array[length]={6,4,2,9,1,7,3,10};
int x=5;
selection(array,length,x);
printArray(array,0,length);
return 0;
}
I havent implemented the a recursive solution because things I tried kept giving segmentation faults because I was reaching outside the array.
Can anyone do this recursivly without for or while. I guess you need to split the array and look at it half by half

Here you are.
#include <stdio.h>
void partition( int a[], size_t n, int pivot )
{
if ( !( n < 2 ) )
{
if ( *a < pivot )
{
partition( a + 1, n - 1, pivot );
}
else
{
if ( *( a + n - 1 ) < pivot )
{
int tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
partition( a + 1, n - 2, pivot );
}
else
{
partition( a, n - 1, pivot );
}
}
}
}
int main(void)
{
int a[] = { 4, 6, 2, 9, 1, 7, 3, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
int pivot = 5;
partition( a, N, pivot );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
4 6 2 9 1 7 3 10
4 3 2 1 9 7 6 10
Or also with a recursive definition of the function printArray.
#include <stdio.h>
void partition( int a[], size_t n, int pivot )
{
if ( !( n < 2 ) )
{
if ( *a < pivot )
{
partition( a + 1, n - 1, pivot );
}
else
{
if ( *( a + n - 1 ) < pivot )
{
int tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
partition( a + 1, n - 2, pivot );
}
else
{
partition( a, n - 1, pivot );
}
}
}
}
void printArray( const int a[], size_t n )
{
if ( n )
{
printf( "%d ", *a );
printArray( a + 1, n - 1 );
}
else
{
putchar( '\n' );
}
}
int main(void)
{
int a[] = { 4, 6, 2, 9, 1, 7, 3, 10 };
const size_t N = sizeof( a ) / sizeof( *a );
printArray( a, N );
int pivot = 5;
partition( a, N, pivot );
printArray( a, N );
return 0;
}
The recursive function printArray also can be defined the following way
void printArray( const int a[], size_t n )
{
n == 0 ? ( void )putchar( '\n' )
: ( printf( "%d ", *a ), printArray( a + 1, n - 1 ) );
}

Related

how to make recursive function that find the index of the biggest number in array?

I'm trying to find the index of the biggest number in array, by using a recursive function, but it doesn't work for me.
I wrote this code in "Online C Complier":
#include <stdio.h>
int max(int arr[], int n){
if (n==0) {
return 0;
}
int temp = max(arr, n-1);
if (arr[temp] > arr[n]) {
return temp;
}
else {
return n;
}
}
int main()
{
int arr[] = {20,2,44,6,1,15,25,40};
printf("The index is: %d\n", max(arr, 8));
return 0;
}
The out put is sometimes 8 which is wrong and sometimes 2 which is correct.
thanks u all!
For starters the first function parameter should have qualifier const because the passed array is not being changed within the function.
This part of the function
int temp = max(arr, n-1);
if (arr[temp] > arr[n]) {
return temp;
}
else {
return n;
}
is incorrect. For example n is not a valid index.
The function can look the following way as shown in the demonstration program below.
#include <stdio.h>
size_t max( const int arr[], size_t n )
{
if ( n > 1 )
{
size_t i = max( arr + 1, n - 1 ) + 1;
return arr[0] < arr[i] ? i : 0;
}
else
{
return 0;
}
}
int main( void )
{
int arr[] = { 20, 2, 44, 6, 1, 15, 25, 40 };
const size_t N = sizeof( arr ) / sizeof( *arr );
printf( "The index is: %zu\n", max( arr, N ) );
}
The program output is
The index is: 2
Or using your approach the function can look like
size_t max( const int arr[], size_t n )
{
if ( n > 1 )
{
size_t i = max( arr, n - 1 );
return !( arr[i] < arr[n-1] ) ? i : n - 1;
}
else
{
return 0;
}
}

Set typedef that can be 2 different types

I am trying to make a function that can receive a variable which can be a char or an int and for that I have to give the variable a type but I don't know what to put because I want it to be able to receive both.
My code is like this and i don't know what to put in the spot where is written 'IDK':
#include <stdio.h>
#include <string.h>
int is_string = 0;
#define less(A,B) (!is_string ? ((A)<(B)) : (strcmp(A,B)<0))
void merge(IDK a[], int l, int m, int r)
{
IDK aux[10000][20];
int i, j, k;
for (i = m+1; i > l; i--) aux[i-1] = a[i-1];
for (j = m; j < r; j++) aux[r+m-j] = a[j+1];
for (k = l; k <= r; k++){
if (less(aux[j], aux[i])) a[k] = aux[j--];
else a[k] = aux[i++];
}
}
void mergesort(IDK a[], int l, int r) {
int m = (r+l)/2;
if (r <= l)
return;
mergesort(a, l, m);
mergesort(a, m+1, r);
merge(a, l, m, r);
}
int main(){
mergesort(a,left,right);
}
I want the 'IDK' to be char when the variable is_stringis 1, and int when else...
The goal is to use the function to sort words alphabetically or numbers (lowest to highest), the function just has to sort one type of object at a time, but I want it to be able to sort both types of objects so I don't have to repeat code.
I want to have a program that chooses (at runtime) what type it needs to sort.
Thanks
The general approach of writing such functions in C is to declare a function that accepts a pointer of the type void * together with the number of elements in the passed array, the size of an object of the array element type and a comparison function similarly how the standard C function qsort is declared.
Here is a demonstrative program that shows such an approach.
The function merge can be written without allocating dynamically memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void merge( void *a, size_t m, size_t n, size_t size, int cmp( const void *, const void * ) )
{
void *p = malloc( n * size );
size_t i = 0, j = m;
char *pos = p;
while ( i < m && j < n )
{
if ( cmp( ( char * )a + j * size, ( char *)a + i * size ) < 0 )
{
memcpy( pos, ( char * )a + j * size, size );
++j;
}
else
{
memcpy( pos, ( char * )a + i * size, size );
++i;
}
pos += size;
}
if ( i < m )
{
memcpy( pos, ( char * )a + i * size, ( m - i ) * size );
}
if ( j < n )
{
memcpy( pos, ( char * )a + j * size, ( n - j ) * size );
}
memcpy( a, p, n * size );
free( p );
}
void mergesort( void *a, size_t n, size_t size, int cmp( const void *, const void * ) )
{
if ( n / 2 )
{
mergesort( a, n / 2, size, cmp );
mergesort( ( char * )a + n / 2 * size, n - n / 2, size, cmp );
merge( a, n / 2, n, size, cmp );
}
}
int cmp_int( const void *p1, const void *p2 )
{
int a = *( int * )p1;
int b = *( int * )p2;
return ( b < a ) - ( a < b );
}
int cmp_string( const void *p1, const void *p2 )
{
return strcmp( *( const char * const * )p1, *( const char * const * )p2 );
}
int main(void)
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N1 = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
mergesort( a, N1, sizeof( *a ), cmp_int );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
char * s[] = { "J", "I", "H", "G", "F", "E", "D", "C", "B", "A" };
const size_t N2 = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
mergesort( s, N2, sizeof( *s ), cmp_string );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
return 0;
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
J I H G F E D C B A
A B C D E F G H I J
You're looking for a union, but that won't work with your calls to scanf and printf. They expect a certain type of argument depending on the format modifier, in this case expecting an int or int* for modifier "%d".
union IDK
{
int int_val;
char *string_val;
};
void merge(union IDK a[], int l, int m, int r);
What you read from the console is always a string. scanf can convert it to a number, if that's what you ask for with "%d". But it appears that what you really are looking for is a way to sort strings that may consist of digits. The easiest way to do that is to try to convert it using strtol.
There's another pitfall you should be aware of. strcmp compares the ASCII values of characters. This won't sort alphabetically, if that's what you're looking for.
Note that a generalized sorting function is usually implemented by passing it a void*, the number of elements, the size of those elements, and a function pointer to a comparison function. See qsort for an example.

What's wrong with this function that reverses arrays using recursivity? ( code and outcome included )

So this is the code I wrote, trying to reverse that array t using recursivity
#include <stdio.h>
#include <stdlib.h>
void rev(int n, float *t)
{
float x;
if(n==0)
{
return 0 ;
}
else
{
x=*t;
*t=*(t+(n-1));
*(t+(n-1))=x;
return rev(n-1, t+1);
}
}
void main()
{
int i;
float t[]={1,2,3,4,5,6,7,8,9};
int n=sizeof t /sizeof *t;
rev (n,t);
for(i=0;i<n;i++) printf("%f",t[i]);
}
I'd like to understand why this solution does not work, I'm not that interested in the solution overall but I want to understand what mistakes I made in this one for it not to work.
For starters a function that has the return type void shall return nothing value. So this statement
return 0 ;
is invalid.
The function swaps two elements so the size of the array must be decremented by 2.
The function can look like
void rev( float a[], size_t n )
{
if ( !( n < 2 ) )
{
float tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
rev( a + 1, n - 2 );
}
}
and be called like
size_t n = sizeof t /sizeof *t;
rev( t, n);
Here is a demonstrative program.
#include <stdio.h>
void rev( float a[], size_t n )
{
if ( !( n < 2 ) )
{
float tmp = *a;
*a = *( a + n - 1 );
*( a + n - 1 ) = tmp;
rev( a + 1, n - 2 );
}
}
int main(void)
{
float a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
size_t n = sizeof a /sizeof *a;
for ( size_t i = 0; i < n; i++ )
{
printf( "%.0f ", a[i] );
}
putchar( '\n' );
rev( a, n );
for ( size_t i = 0; i < n; i++ )
{
printf( "%.0f ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1
Pay attention to that according to the C Standard the function main shall be declared like
int main( void )
instead of
void main()
There are small easy to fix problems like return 0; and return rev(n-1, t+1);. The first one should be just
return;
because you can't return anything from a function returning void.
The other should be a call to rev() itself
rev(n-1, t+1);
because that's what recursive functions do (and also because you can't return anything)
Then you should use int main( void ) or at least int main() Difference between int main() and int main(void)?
Finally, you have a logic error here
x=*t;
*t=*(t+(n-1));
*(t+(n-1))=x;
rev(n-1, t+1);
*(t+(n-1)) will always be the value of the last element of the array: yes you pass n-1 so you expect that if *(t+(n-1)) was 8th element, in the next call it will be 7th, however you are also passing t+1 so *(t+(n-1)) will always be the 8th element of the array.
And even this one is an easy-to-fix problem. You just pass n-2.
Here's your recursive function
void rev(int n, float *t)
{
float x;
if(n > 0) {
x=*t;
*t=*(t+(n-1));
*(t+(n-1))=x;
rev(n-2, t+1);
}
return;
}
Doing
if(n != 0) {
.... something....
}
return;
Is the same of doing
if(n == 0) {
return;
}
else {
... something...
}
I put n > 0 instead of n != 0 because since n is always initially positive the two conditions are equivalent, however since you pass n-2 if n is an odd number you are going to have negative values of n without passing for 0.

Most long series of element in array

I've prepared a code that should found the longer series of elements in growing order .for example ,in arrays exists following elements : 1 2 3 4 5 2 7 6 7 9,output will 5 (the series from 1 to 5) ,function will return integer tempcount that include numbers of element and print it.but get an error ,the function
isn't working:
#include "stdafx.h"
#include <stdio.h>
int find_maximum(int[], int);
int main() {
int c, array[100], size, location, maximum,found;
scanf_s("%d", &size);
for (c = 0; c < size; c++)
scanf_s("%d", &array[c]);
location = find_maximum(array, size);
maximum = found;
printf("Maximum elements = %d ", maximum);
return 0;
}
int find_maximum(int a[], int n) {
int c, index = 0,count =1,tempCount=1;
for (c = 1; c < n; c++)
if (a[c] > a[index])
count +=1;
else
{
if (count > tempCount)
{
tempCount=count;
}
}
return tempCount;
}
The variables maximum and found are not initialized and are used nowhere except this statement that does not make sense
maximum = found;
You are storing the length of the maximum subsequence in the variable location
location = find_maximum(array, size);
It is the variable value which you need to output.
The function find_maximum also does not make sense. For example you are comparing elements of the array with the same element at position 0.
int c, index = 0,count =1,tempCount=1;
^^^^^^^^^
for (c = 1; c < n; c++)
if (a[c] > a[index])
count +=1;
//…
The function can be declared and implemented as it is shown in the demonstrative program below.
#include <stdio.h>
size_t max_ascending_seq( const int a[], size_t n )
{
size_t max_n = 0;
for ( size_t i = 0; i < n; )
{
size_t current_n = 1;
while ( ++i < n && a[i-1] < a[i] ) ++current_n;
if ( max_n < current_n ) max_n = current_n;
}
return max_n;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 2, 7, 6, 7, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t max_n = max_ascending_seq( a, N );
printf( "%zu\n", max_n );
return 0;
}
The program output is
5
A more generic function can be written the following way.
#include <stdio.h>
size_t max_ascending_seq( const int a[], size_t n, int predicate( int, int ) )
{
size_t max_n = 0;
for ( size_t i = 0; i < n; )
{
size_t current_n = 1;
while ( ++i < n && predicate( a[i-1], a[i] ) ) ++current_n;
if ( max_n < current_n ) max_n = current_n;
}
return max_n;
}
int less_than( int x, int y )
{
return x < y;
}
int greater_than( int x, int y )
{
return y < x;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 2, 7, 6, 7, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t max_n = max_ascending_seq( a, N, less_than );
printf( "%zu\n", max_n );
max_n = max_ascending_seq( a, N, greater_than );
printf( "%zu\n", max_n );
return 0;
}
The program output is
5
2

c sorting with recursion

I'm trying to write a sorting function with just recursion. I keep getting the error:
lvalue required as unary '&' operand
This are the functions I'm using:
void sorter_rec (int a[], int n) {
if (n ==1 ) return;
else {
swap( &(maximumrec(a,n)), &a[n-1]);
sorter_rec(a,n-1);
return;
};
}
The error is in sorter_rec.
void swap(int *px, int *py)
{ int z = *px;
*px = *py;
*py = z;
return;
}
int maximumrec(int ar[], int n)
{
if (n == 1) {
return ar[0];
} else {
int max = maximumrec(ar, n-1);
return ar[n-1] > max ? ar[n-1] : max;
}
}
How can I solve this?
You may not apply the operator & to the temporary object returned by the function maximumrec.
Also if you are using the selection sort starting from the end of array then the maximum element should be also searched starting from the end of array. In this case the sorting algorithm will be more stable.
Here is a demonstrative program that uses your approach but instead of the searching maximum element it searches minimum element. You can rewrite it such a way that it would search the maximum element if you want.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define N 20
int * min_element( int a[], size_t n )
{
int *min = a;
if ( !( n < 2 ) )
{
min = min_element( a + 1, n - 1 );
min = *min < *a ? min : a;
}
return min;
}
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void sort( int a[], size_t n )
{
if ( !( n < 2 ) )
{
int *min = min_element( a, n );
if ( min != a ) swap( a, min );
sort( a + 1, n - 1 );
}
}
int main(void)
{
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] );
printf( "\n" );
sort( a, N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
printf( "\n" );
return 0;
}
The program output might look like
17 9 12 15 1 17 19 17 6 2 14 19 2 8 5 19 0 12 16 8
0 1 2 2 5 6 8 8 9 12 12 14 15 16 17 17 17 19 19 19
Your basic algorithm works. All I had to do was fix up the way you passed pointers around, and it worked the first time! Hope this helps. I changed some names to fit my own style a bit, and added some convenience things (macro and logging method), and main() so I could test it.
Note that the name of an array is the same as &array[0]
#include <stdio.h>
#define INT_COUNT(n) (sizeof(n) / sizeof(int))
void dumpIntArray(int *array, int n) {
printf("{ ");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf(" }\n");
}
void swap(int *px, int *py) {
int z = *px;
*px = *py;
*py = z;
return;
}
int *ptrToMax(int *sortable, int n) {
if (n == 1) {
return sortable;
} else {
int *maximum = ptrToMax(sortable, n - 1);
return sortable[n - 1] > *maximum ? &sortable[n - 1] : maximum;
}
}
void quicksort(int *sortable, int n) {
if (n == 1 ) {
return;
} else {
swap(ptrToMax(sortable, n), &sortable[n - 1]);
quicksort(sortable, n - 1);
return;
}
}
int main(int argc, char **argv) {
int foo[] = { 1, 5, 3, 2, 4, 9, 10, 8, 7 };
printf("Before:\n");
dumpIntArray(foo, INT_COUNT(foo));
quicksort(foo, INT_COUNT(foo));
printf("After:\n");
dumpIntArray(foo, INT_COUNT(foo));
}

Resources