C - Recursion with pointers - c

I am trying to write a recursion function that takes an array as an argument and returns the MIN and MAX values. So far i can only get MAX. I tried to add a pointer to send back the minimum value but for some reason, it always crashes and shows lots of warnings.
Please help me figure out what is wrong in my code.
int MinMaxArray(int arr[], int size, int* min)
{
if (size == 1)
return arr[0];
if (arr[size - 1] > MinMaxArray(arr, (size - 1), &min))
return arr[size - 1];
else
return MinMaxArray(arr, (size - 1), &min);
}
so i tried this but the min that return is allways the one in index 0
how to make it works?
int MinMaxArray(int arr[], int size, int* min)
{
if (size == 1)
{
*min = arr[0];
return arr[0];
}
if (arr[size - 1] < MinMaxArray(arr, (size - 1), min))
*min = arr[size - 1];
else
*min = MinMaxArray(arr, (size - 1), min);
if (arr[size - 1] > MinMaxArray(arr, (size - 1), min))
return arr[size - 1];
else
return MinMaxArray(arr, (size - 1), min);
}

like this
#include <stdio.h>
#include <assert.h>
int MinMaxArray(int arr[], int size, int *min){
assert(arr != NULL && size > 0);
if (size == 1){
*min = arr[0];
return arr[0];
}
int max = MinMaxArray(arr, size - 1, min);
if (arr[size - 1] < *min)
*min = arr[size - 1];
return (arr[size - 1] > max) ? arr[size - 1] : max;
}
int main(void) {
int arr[] = { 1,5,9,2,6,-4,8,3,7 };
int min, max = MinMaxArray(arr, sizeof(arr)/sizeof(*arr), &min);
printf("max:%d, min:%d\n", max, min);
return 0;
}

The third argument specified for the call
MinMaxArray(arr, (size - 1), &min)
has wrong type relative to the parameter declaration.
The argument has type int ** while the parameter has type int *.
Also the minimum element is not calculated.
In C++ there is standard algorithm named minmax_element that returns a pair of pointers that point to the maximum an minimum elements of an array.
You could use a similar declaration of the function written in C.
Another approach is to return a pair of indices of the minimum and maximum elements.
To do so you need to declare a structure of two data members.
Below there is shown how the function that returns a pair of indices can be implemented in C.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct MinMax
{
size_t min;
size_t max;
};
struct MinMax minmax_element( const int a[], size_t n )
{
struct MinMax minmax = { 0, 0 };
if ( n > 1 )
{
struct MinMax current = minmax_element( a + 1, n - 1 );
++current.min; ++current.max;
if ( a[current.min] < a[minmax.min] ) minmax.min = current.min;
if ( a[minmax.max] < a[current.max] ) minmax.max = current.max;
}
return minmax;
}
#define N 10
int main(void)
{
int a[N];
srand( ( unsigned int )time(NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i]= rand() % ( 2 * N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
struct MinMax minmax = minmax_element( a, N );
printf( "The minimum is %d\n", a[minmax.min] );
printf( "The maximum is %d\n", a[minmax.max] );
return 0;
}
Its output might look like
14 6 7 9 6 7 15 12 0 10
The minimum is 0
The maximum is 15
Take into account that the user can pass to the function an "empty" array that is when the argument that corresponds to the size of the array is equal to 0. In this case your own function implementation has undefined behavior.
If you may not use a structure then the function can be declared like
void minmax_element( const int a[], size_t n, size_t *min, size_t *max );
Or
void minmax_element( const int a[], size_t n, int **min, int **max );
It will not be difficult to change the shown above recursive function according to these declarations.
For example
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void minmax_element( const int a[], size_t n, size_t *min, size_t *max )
{
*min = 0;
*max = 0;
if ( n > 1 )
{
size_t cur_min, cur_max;
minmax_element( a + 1, n - 1, &cur_min, &cur_max );
++cur_min; ++cur_max;
if ( a[cur_min] < a[*min] ) *min = cur_min;
if ( a[*max] < a[cur_max] ) *max = cur_max;
}
}
#define N 10
int main(void)
{
int a[N];
srand( ( unsigned int )time(NULL ) );
for ( size_t i = 0; i < N; i++ ) a[i]= rand() % ( 2 * N );
for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
putchar( '\n' );
size_t min;
size_t max;
minmax_element( a, N, &min, &max );
printf( "The minimum is %d\n", a[min] );
printf( "The maximum is %d\n", a[max] );
return 0;
}

Related

How to get all the elements of an array that are divisible with 3 and then sum them thogether?

I dont know how to get the code to print out the elements that are divisable with 3 and the print out the sum of those elements , can someone help me do it , thanks for your time!
Code:
#include <stdio.h>
int sum(int arr[]){
int n = sizeof(arr) / sizeof(arr[0]);
int sum = 0;
for (int y=0;y<n;y++){
sum += arr[y];
printf("%d",sum);
}
}
int main() {
int F[5] = {1,3,5,9,8};
int s = 0;
for (int i=0;i<5;i++){
if (F[i]%3 == 0) {
int diviz[] = {F[i]};
printf("%d\n",diviz[0]);
sum(diviz);
}
}
return 0;
}
Expected Output:
3
9
12
Actual Output:
3
349
910
Idk how to solve this issue
This function declaration
int sum(int arr[]){
is adjusted by the compiler to the declaration
int sum(int *arr){
That is within the function the variable arr has the pointer type int *.
Thus the declaration with sizeof expression
int n = sizeof(arr) / sizeof(arr[0]);
is equivalent to
int n = sizeof( int * ) / sizeof( int );
and yields either 2 or 1 depending on the size of the pointer.
On the other hand, this call of the function
int diviz[] = {F[i]};
printf("%d\n",diviz[0]);
sum(diviz);
in any case does not make a great sense because instead of passing the original array you are passing an array that contains only one element. And the for loop in main is redundant.
You need explicitly to pass the number of elements in the array.
So the function can look like
long long int sum( const int arr[], size_t n, int divisor )
{
long long int sum = 0;
for ( size_t i = 0; i < n; i++ )
{
if ( arr[i] % divisor == 0 ) sum += arr[i];
}
return sum;
}
And the function can be called like
int arr[] = {1,3,5,9,8};
const size_t N = sizeof( arr ) / sizeof( *arr );
int divisor = 3;
printf( "The sum of elements divisible by %d = %lld\n", divisor, sum( arr, N, divisor ) );
The function will be more safer if to add a check whether divisor is passed equal to 0 as for example
long long int sum( const int arr[], size_t n, int divisor )
{
long long int sum = 0;
if ( divisor != 0 )
{
for ( size_t i = 0; i < n; i++ )
{
if ( arr[i] % divisor == 0 ) sum += arr[i];
}
}
return sum;
}
int main() {
int F[5] = {1,3,5,9,8};
int s = 0;
for (int i=0;i<5;i++){
if (F[i]%3 == 0) {
s = s + F[i];
printf("%d",F[i]);
}
}
printf("%d",s); //print sum total
return 0;
}

How can I print the number of unique elements instead of show the elements itself in my code?

I want to print the number of unique elements instead of show the elements For example show 4. Means we have 4 unique elements
#include<stdio.h>
#define max 100
int ifexists(int z[], int u, int v)
{
int i;
for (i=0; i<u;i++)
if (z[i]==v) return (1);
return (0);
}
void main()
{
int p[max], q[max];
int m;
int i,k;
k=0;
printf("Enter length of the array:");
scanf("%d",&m);
printf("Enter %d elements of the array\n",m);
for(i=0;i<m;i++ )
scanf("%d",&p[i]);
q[0]=p[0];
k=1;
for (i=1;i<m;i++)
{
if(!ifexists(q,k,p[i]))
{
q[k]=p[i];
k++;
}
}
printf("\nThe unique elements in the array are:\n");
for(i = 0;i<k;i++)
printf("%d\n",q[i]);
}
https://onlinegdb.com/Bk3tvQMpw
Sort the array then iterate through the elements and print out if the current element is different than the last:
int cmpint(const void *a, const void *b) {
return *(int *) a) < *(int *) b :
-1 ?
(
*(int *) b) < *(int *) a ?
1 :
0
);
}
int main() {
/* ... */
qsort(p, m, sizeof(*p), cmpint);
int n = 0;
for(int i = 0; i < m; i++) {
if(!i || p[i-1] != p[i]) n++;
}
printf("Number of unique elements: %d\n", n);
}
where p is your now sorted array and length is m as per example code. As qsort is expected O(m *log(m)) so will this aglorithm. If you don't sort the array it will be O(m^2) due to m linear searches.
If I have understood the question correctly what you need is to count unique elements in an array using a function and without defining an auxiliary array. That is there is no need to output the unique elements themselves.
In this case the corresponding function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
int is_unique( const int a[], size_t n, int value )
{
while ( n != 0 && a[ n - 1 ] != value ) --n;
return n == 0;
}
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
count += is_unique( a, count, a[i] );
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is
There are 3 unique elements in the array.
If you do not want to define one more function to count unique elements in an array then just move the loop in the function shown in the above demonstrative program inside main.
Here you are.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2, 3, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t count = 0;
for ( size_t i = 0; i < N; i++ )
{
size_t j = i;
while ( j != 0 && a[j - 1] != a[i] ) --j;
count += j == 0;
}
printf( "There are %zu unique elements in the array.\n", count );
return 0;
}
The program output is the same as shown above that is
There are 3 unique elements in the array.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
instead of
void main()

Recursive selection sort error 11 when ordering big integers

I have to use the recursive selection sort in order to order different arrays of integers.
These arrays are respectively formed by 100, 1000, 10000, 100000, 200000, 500000 items and can be formed by ordered numbers, partially ordered numbers, inverted ordered numbers and random numbers.
After that I have to calculate the time the algorithm took to order the array.
I have to use recursion, It's a homework.
I created a function that generates the array:
typedef enum {ORINATO, INVERS, PARZ_ORDINATO, RANDOM} Ordine;
int *generaArray(int dimensione, Ordine ordine) {
int i, j, n;
int *array = (int*)malloc(dimensione * sizeof(int));
if (!array){
return NULL;
}
switch (ordine){
case ORINATO:
for (i = 0; i < dimensione; i++){
array[i] = i;
} break;
case INVERS:
n =0;
for ( i = dimensione-1; i >= 0 ; i--) {
array[i] = n;
n++;
}break;
case PARZ_ORDINATO:
for (i = 0; i < dimensione/2 ; i++) {
array[i] = i;
}
for (j = i+1; j <dimensione; j++){
n = rand();
array[j] = n;
};break;
case RANDOM:
for ( i = 0; i <= dimensione ; i++) {
array[i] = rand();
}break;
default:
break;
}
return array;
}
And it works like wonders.
Then I have created the recursive selection sort like follows:
void recursiveSelectionSort(int *array, int dim, int start){
int min=0;
if (start >= dim-1){
return;
}
min = findMin(array, start, start+1, dim);
swap(&array[min], &array[start]);
recursiveSelectionSort(array, dim, start+1);
}
int findMin(int *array, int min, int start, int dim){
if(start == dim ){
return min;
}
if (array[start]< array[min]){
min = start;
}
return findMin(array, min, start+1, dim);
}
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
Now, this as well should work but something clearly isn't. Let's make an example with the implementation, this is what i put in my main:
int main() {
int *array;
clock_t start, end;
double t;
array = generaArray(1000, ORINATO);
start = clock();
recursiveSelectionSort(array, 1000, 0);
end = clock();
t = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("\nIl tempo impiegato per 1000 elementi è: %lf secondi", t);
return 0;
}
This works (but it's slower thank it should be). However if you try and change the dimension from 1000 to 200000 or 500000 it shows error 11.
What is it causing it? I tried everything but it doesn't seem to work.
For starters recursive functions called for large arrays can invoke a stack overflow.
So use non-recursive functions that implement the method selection sort for large arrays.
As for your implementation then for example the function swap has typos.
void swap (int* x, int *y){
int temp = *x;
x = *y;
y = *temp;
}
I think you mean
void swap (int* x, int *y){
int temp = *x;
*x = *y;
*y = temp;
}
All other functions have too many parameters.
For example the function findMin can be declared the following way
size_t findMin( const int *a, size_t n );
and can be also defined as a recursive function (if you decided to write recursive functions then this function can be also recursive)
Here is a demonstrative program that shows how the functions can be defined
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap( int *x, int *y )
{
int temp = *x;
*x = *y;
*y = temp;
}
size_t findMin( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t i = findMin( a + 1, n - 1 ) + 1;
return a[i] < a[0] ? i : 0;
}
}
void recursiveSelectionSort( int a[], size_t n )
{
if ( !( n < 2 ) )
{
size_t i = findMin( a + 1, n - 1 ) + 1;
if ( a[i] < a[0] ) swap( &a[0], &a[i] );
recursiveSelectionSort( a + 1, n - 1 );
}
}
int main(void)
{
enum { N = 15 };
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' );
recursiveSelectionSort( a, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d ", a[i] );
}
putchar( '\n' );
return 0;
}
The program output might look like
11 9 3 5 6 8 2 4 5 3 7 9 2 0 14
0 2 2 3 3 4 5 5 6 7 8 9 9 11 14

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