So I have a task in my training that sounds like this:
Write a subprogram that will recursively find the maximum element from an array and also write the main function to call it.
What I failed to fully understand is what recursion is. I wanted to ask you guys if my code is recursive or not. And if not what changes should I make/ what recursion really means?
#include <stdio.h>
int find_maximum(int[], int);
int main() {
int c, array[100], size, location, maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = array[location];
printf("Maximum element location = %d and value = %d.\n", location + 1, maximum);
return 0;
}
int find_maximum(int a[], int n) {
int c, max, index;
max = a[0];
index = 0;
for (c = 1; c < n; c++) {
if (a[c] > max) {
index = c;
max = a[c];
}
}
return index;
}
Thank you all for your time!
Problems that are well-suited to recursion can be broken down into smaller, simpler subproblems. This is one of the things that gives recursion its power. When trying to use recursion to solve a problem, it usually seems best to try to break the problem down into simpler subproblems in finding your way to a solution.
You might notice that in finding the maximum value stored in an array, it is either the value of the first element, or the maximum value of the remaining elements. This breaks the problem into two parts: if the first element is larger than any remaining elements, you are done; otherwise, you must continue and see if the next element is larger than the remaining elements. In code, this might look like:
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
Here, there is a base case: if rest_sz is 1, there is no need to look further; the value of first element (curr_val = rest[0]) is the maximum, and that value is returned. If the base case is not satisfied, execution of the function continues. max_in_rest is the result from the recursive function call max_in(rest_sz-1, rest+1). Here rest_sz-1 indicates the number of elements remaining in the portion of the array indicated by rest+1. In the new function call, the base case is met again, and eventually this case will be true since rest_sz is decremented with each recursive call. When that happens, the value of curr_val in the current stack frame will be returned; note that this value is the value of the last element in the array. Then, when the function returns to its caller, max_in_rest in that frame will get the returned value, after which the larger of curr_val or max_in_rest is returned to the previous caller, and so on, until finally control is returned to main().
Using pencil and paper to diagram each function call, the values of its variables, and what is returned would help to understand exactly how this recursion works.
You can apply the same method to solving the problem of finding the index of the maximum value of an array. In this case, if the value of the first element is greater than the value of any remaining elements, then the index of the maximum element is the index of the first element; otherwise the index of the maximum element is the index of the maximum value of the remaining elements. In code, this might look like:
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
There is just a little more information to keep track of this time. Here, if the base case is satisfied, and rest_sz is 1, then there is no reason to look further, the current index curr_ndx is the index of the maximum value. Otherwise, find_max_r() is recursively called, with rest incremented to point to the remaining elements of the array, and rest_sz suitably decremented. This time, curr_ndx is keeping track of the current index with respect to the original array, and this value is passed into each function call; also, a pointer to the first element of the original array, arr, is passed into each function call so the index value curr_ndx can access the values from the original array.
Again, when the base case is reached, the current position in the array will be the end of the array, so the first elements to be compared in the return statement will be towards the end of the array, moving towards the front of the array. Note that >= is used here, instead of > so that the index of the first maximum value is returned; if you instead want the index of the last maximum value, simply change this to >.
Here is a complete program. Note the use of the helper function find_max() to call the recursive function find_max_r(), which allows the caller to use a function with the same signature that the posted code uses (except for the use of size_t types, which is really the correct type for array indices):
#include <stdio.h>
int max_in(size_t sz, int *rest);
size_t find_max(size_t sz, int arr[]);
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx);
int main(void)
{
int array[] = { 2, 7, 1, 8, 2, 5, 1, 8 };
size_t array_sz = sizeof array / sizeof array[0];
int max_val = max_in(array_sz, array);
printf("Maximum value is: %d\n", max_val);
size_t max_ndx = find_max(array_sz, array);
printf("Maximum value index: %zu\n", max_ndx);
return 0;
}
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
size_t find_max(size_t sz, int arr[])
{
int *rest = arr;
return find_max_r(arr, rest, sz, 0);
}
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
Program output:
Maximum value is: 8
Maximum value index: 3
Think of calculating the maximum number in an array as the number which will be maximum of the first element and the maximum of the remaining elements of the array. Something like: max(first_elem, max(remaining_elems)).
The actual recursive function: find_max quite simple, if there is just a single element in the array, that element is returned. Otherwise, we get the maximum of the first element and the remaining elements of the array.
#include <stdio.h>
// function to find the max of 2 numbers
int max(int x, int y)
{
return (x > y) ? x : y;
}
// the recursive function
int find_max(int *p, int n)
{
if (n == 1) return *p;
return max(*p, find_max(p + 1, n - 1));
}
int main(void)
{
int arr[] = {23, 3, 11, -98, 99, 45};
printf("max: %d\n", find_max(arr, sizeof arr / sizeof arr[0]));
}
No, your code does not use recursion. Recursion is when a function calls itself, or calls another function which leads to a call to itself again.
You can change your code like this to have a recursive, stateless function that can determine the maximum value of the array.
int find_maximum(int a[], int n) {
return find_maximum_r(a, 0, n);
}
int find_maximum_r(int a[], int index, int n) {
if (index + 1 == n) {
return a[index];
}
int maxRight = find_maximum_r(a, index + 1, n);
return a[index] > maxRight ? a[index] : maxRight;
}
No, your code is recursive only if you call the function find_maximum from itself directly or indirectly.
As your function is trying to get not only the maximum value, but also the position in the array, I have modified slightly the interface to return the reference (that is, a pointer to the value) so we can infer the position of the array element directly from the subtraction of element pointers. This way, I can pass to the function the array pointer directly and the array size, and then divide the array in two halves, and applying the same function to the two halves (it can be demonstrated that if some element is the maximum value of the array, it has to be greater than or equal to each half's maximum) For the same reason, I have modified some of the variables defined in your main() function, to allow for references to be used:
max.c
#include <stdio.h>
#include <assert.h>
int *find_maximum(int a[], int n); /* return a reference pointer to the maximum value */
int main() {
int c, array[100], size, *location, /* location must be a pointer */
maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
assert(size >= 1);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = *location; /* access to the value is granted by pointer dereference */
printf("Maximum element location = %td and value = %d.\n",
location - array, /* pointer difference gives the array position */
maximum);
return 0;
} /* main */
/* somewhat efficient recursive way of a divide and conquer method
* to get the maximum element reference. */
int *find_maximum(int a[], int n)
{
if (n == 1) return a; /* array of 1 element */
int *left = find_maximum(a, n/2), /* left half begins at a
* and has n/2 elements */
*right = find_maximum(a + n/2, (n+1)/2); /* right half begins
* at a + n/2, and
* has (n+1)/2
* elements */
return *left > *right
? left
: right;
} /* find_maximum */
As you see, I have to divide by two, but as I have arrays of any length, I have to be careful not to leave out any element in the next step. This is the reason for using an array of (n+1)/2 elements in the right half of the recursive call to the function. I include n/2 elements in the first half (rounding down), I have to include (n+1)/2 elements (rounding up) in the right half, to be sure that I include all the array elements in the two halves.
First of all, recursion means - function calling itself.
And what you've written is not recursive function. I'll post the most simple way to find biggest or largest element in an array, using recursion.
#include<stdio.h>
#define N 5
int biggest(int num[], int n, int big)
{
if(n < 0)
return big;
else
{
if(big < num[n])
big = num[n];
return biggest(num, --n, big);
}
}
int main()
{
int a[N], i;
printf("Enter %d integer number\n", N);
for(i = 0; i < N; i++)
scanf("%d", &a[i]);
printf("Biggest Element in the array: %d\n", biggest(a, N - 1, a[0]));
return 0;
}
Source: C Program To Find Biggest Element of An Array using Recursion
NO it is not recursive function
to know about recursion this link is very useful https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursion/
to make a recursion function to solve your problem try this
you can try this pseudo code declare your array global and a max=0 global and size global
int find_maximum(int i)
{
if (i == size )
return max;
else if ( max < array[i])
max =array [i];
return find_maximum(i+1);
}
where i is the array index
No, your program is certainly not recursive. As the definition, recursive function must call itself with a terminating condition.
Please read TutorialsPoint about recursion in C.
Update on #JonathanLeffler's comment:
Please note that the output in the reference will overflow.
Related
I'm a newbie both here in stackoverflow and both in the world of programming.
Today i was solving some exercise about recursion, and one of these asked to write a recursive function for finding minimum element of an array.
After many tries, I have finally wrote this working code, but i want to ask you if this is a "good" code. I mean, the fact it's working aside, is it written well? There's something that should be changed? And, above all, there's a way to make this functions working well without declaring that global int "min"? :)
Here's the code:
#include <stdio.h>
int recursiveMinimum(int array[], size_t size);
int min = 1000;
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
printf("\nMinimum element of this array is: %d\n\n",
recursiveMinimum(array, 6));
}
int recursiveMinimum(int array[], size_t size) {
if (size == 1) {
return min;
} else {
if (array[size] <= min) min = array[size];
return min = recursiveMinimum(array, size - 1);
}
}
It is a bad idea when a function depends on a global variable.
But in any case your function is incorrect and invokes undefined behavior.
In the first call of the function this if statement
if (array[size] <= min) min = array[size];
trying to access memory outside the passed array because the valid range of indices is [0, size).
Also the array can contain all elements greater than the initial value of the global variable
int min = 1000;
And the function may not be called a second time because the value of the variable min is unspecified.
The function should return the index of the minimal element in the array. In general the user can pass the second argument equal to 0. In this case again the function will invoke undefined behavior if you will try to return a non-existent element of an empty array.
The function can be declared and defined the following way
size_t recursiveMinimum( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
Here is a demonstration program
#include <stdio.h>
size_t recursiveMinimum( const int a[], size_t n )
{
if (n < 2)
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
int main( void )
{
int a[] = { 55, 5, 1, 27, 95, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min = recursiveMinimum( a, N );
printf( "\nMinimum element of this array is: %d at the position %zu\n",
a[min], min );
}
The program output is
Minimum element of this array is: 1 at the position 2
Pay attention to that the first parameter has the qualifier const because the passed array is not being changed within the function. And to decrease the number of recursive calls the function calls itself for two halves of the array.
Recursion works by reducing the size at the call to the next iteration and comparing the result of the call with the current value and return the lower of the 2.
As recursion stop you can simply return the first element
int recursiveMinimum(int array[], size_t size) {
if (size == 1) return array[0];
int min_of_rest = recursiveMinimum(array, size - 1);
if (array[size - 1] <= min_of_rest) return array[size - 1];
return min_of_rest;
}
Full example: https://godbolt.org/z/sjnh8sYz3
In the past, we used to implement it with pointers, KR-C style.
Using pointers in a harsh way was a mean to deal with inefficiency of compilers at that time.
Not sure it is considered good practice now. An example is provided hereafter.
Anyway, it would be better (easier and more efficient) to implement it in a non recursive manner.
#include <stdio.h>
void recursiveMinimum(int *array, size_t size, int *min) {
if (size == 0) return;
if (*array < *min) *min = *array;
recursiveMinimum (array+1, size-1, min);
return;
}
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
size_t size = sizeof(array)/sizeof(*array);
int min = array[0];
recursiveMinimum (array, size, &min);
printf("\nMinimum element of this array is: %d\n", min);
return 0;
}
I'm trying to make a function that identifies the maximum value in an array and calculate the sum of each time it appears. That's fine but the problem is that I need to make the function args the size of the array and the array itself.
This is what I've come up this far:
int sum(int a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<=tam;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
The argument "a" is the array and the size is the size of the array. I get errors saying "a" is neither array nor pointer nor vector.
Any help is apreciated.
Replace int sum(int a, int size) to int sum(int *a, int size) or int sum(int a[], int size)
This function declaration
int sum(int a, int size);
declares a function with two parameters of the type int. If you mean that the first parameter should specify a one-dimensional array then the function declaration will look like
int sum(int a[], int size);
or
int sum( int *a, int size);
because a parameter having an array type is adjusted by the compiler to pointer to the array element type.
Also your function returns nothing though its return type is not void.
Moreover the function uses undeclared variables as for example the variable tam.
And if an array has size elements then the valid range of indices is [0, size ).
Also the function should not change the passed array. And to avoid integer overflow the return type should be long long int.
Also the function should not output any message. It is the caller of the function that decides whether to output a message.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
long long int sum( const int a[], size_t n )
{
long long int total = n == 0 ? 0 : a[0];
size_t max = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[max] < a[i] )
{
total = a[i];
max = i;
}
else if ( !( a[i] < a[max] ) )
{
total += a[max];
}
}
return total;
}
int main(void)
{
int a[] = { 2, 8, 8, 9, 7, 3, 8, 1, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
printf( "The sum of elements with the maximum value is %lld\n", sum( a, N ) );
return 0;
}
The program output is
The sum of elements with the maximum value is 18
#include<stdio.h>
#include<stdlib.h>
int sum(int *a, int size);
int main()
{
int *a=(int*)malloc(10*sizeof(int));
for(int i=0;i<10;i++)
a[i]=i+1;
sum(a,10);
}
int sum(int *a, int size)
{
int i, max, output=0;
//checking every index for max value
for(i=0;i<size;i++){
if(i==1){
//setting max on the first index
max=a[i];
}else{
if(a[i]>max){
a[i]=max;
}
}
}
//making the sum
for(i=0;i<size;i++){
if(a[i]==max);
output=output+max;
}
printf("%d", output);
}
Well, you can do it in just one pass, as when you identify a new maximum, the accumulated sum of the last is no longer valid (it refers not to the biggest number, but to one smaller)
There's something in your code that is weird... you start the loop at 0, and then compare if (i == 1) which I guess is a mistake (shouldn't it be 0?), as you should want to check if you are at the first (and not at the second cell) to do the initialization of max. Anyway, there's a clever way to do is to initialize max to the minimum number you can have (and for an int you have that value in <limits.h> as the constant INT_MIN). I'll show you now one possible source code to your problem (taken from yours, but changed some variables and added others to show you that in one pass you can do a lot of work:
#include <stdio.h>
#include <limits.h>
/* pretty format of output with location of trace in source file
*/
#define F(_fmt) __FILE__":%d:%s: "_fmt,__LINE__,__func__
/* to pass an array, just declare it as below. The array size is
* unspecified because your don't know it before calling sum,
* and this is the reason to pass the array size. */
int sum(int a[], int size)
{
int i, pos0 = -1, pos1 = -1, max = INT_MIN, output=0;
/* checking every index for max value, and output, you made
* an error here and used tam instead of size. */
for(i = 0; i <= size; i++){
if (a[i] > max) { /* if greater than max */
pos0 = i; /* save position as first */
max = a[i]; /* save max value */
output = max; /* initialize output to max */
} else if (a[i] == max) { /* if equal to max */
pos1 = i; /* save position as last */
output += max; /* add to output */
} /* else nothing */
}
/* print all the values we got */
printf(F("pos0 = %d, pos1 = %d, max = %d, output = %d\n"),
pos0, pos1, max, output);
return output; /* return the requested sum */
}
int list[] = { 3, 2, 5, 6, 5, 4, 7, 3, 7, 4, 7, 2, 1, 6, 2 };
/* max is located ^ ^ ^ in these positions
* 6 8 10 */
/* the following macro gives us the size of the array list by
* dividing the size of the complete array by the size of the
* first element. */
#define n_list (sizeof list / sizeof list[0])
int main()
{
printf(F("result = %d\n"), sum(list, n_list));
}
which should output (if the program is named test from test.c):
$ test
test.c:23:sum: pos0 = 6, pos1 = 10, max = 7, output = 21
test.c:34:main: result = 21
$ _
I'm tasked with writing a function that will identify all the even numbers in an sample array {10,2,9,3,1,98,8] and place them in an array called EvenNumbers. I have to allow the function so that it works with different combinations of numbers in the array not just the numbers in the sample array above.
I'm wondering is there any way to add numbers to an array that could be different every time? How would I extract the even numbers an place them into an array? Also
for the even array size its giving me an error that the expression must have a constant value but when I use const int it still gives me that error.
Here is the full question.
"Using the array of sample values {10,2,9,3,1,98,8}, write a function that will identify all the even numbers in an array and place it in an array called EvenNumbers. The function must work in all cases, not just in the case of the array shown. Assume that the array size is always available through a global constant called MAX"
Here is what I have so far. I've no idea how I will extract the even numbers from a for loop and place them in an array. I also dont know what the "expression must have a constant value" is about?
#include <stdio.h>
#include <stdlib.h>
void EvenNumber(int Array[], int size);
int main()
{
int array[7] = { 10,2,9,3,1,98,8 };
EvenNumber(array, 7);
}
void EvenNumber(int Array[], int size)
{
int i;
int EvenArraySize;
for (i = 0; i < size; i++)
{
if (Array[i] % 2 == 0)
{
EvenArraySize++;
}
}
int Even[EvenArraySize];
}
The right way to go is to use malloc to allocate just the right amount of memory.
Count the number of even numbers
Allocate the space needed to store them
Copy even numbers in this space
Do whatever you want with these numbers
Free the allocated space
Snippet:
#include <stdio.h>
#include <stdlib.h>
#define MAX 7
int
main()
{
int array[] = {10,2,9,3,1,98,8};
int *even_numbers;
int i, nb_even_numbers;
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
nb_even_numbers++;
}
even_numbers = malloc(sizeof(int) * nb_even_numbers);
if (!even_numbers)
{
perror("malloc");
return 1;
}
for (i = 0, nb_even_numbers = 0; i < MAX; i++)
{
if (array[i] % 2 == 0)
even_numbers[nb_even_numbers++] = array[i];
}
/* do your stuff here */
free(even_numbers);
return 0;
}
First, you can never return a statically declared array from a function (even though you don't explicitly try, your Even array is destroyed when EvenNumber returns) Why? The function stack frame for EvenNumber is released for reuse on return and any locally declared arrays are no longer valid.
You either need to pass a second array as a parameter to EvenNumber, or you can dynamically allocate storage for Even in EvenNumber (with, e.g. malloc or calloc or realloc) and return a pointer to the beginning of the array. (you must also have some way to return the size or use a constant for a max size).
There is no need to use % (modulo) to test whether a number is odd/even. All you need to do is look at bit-0 (little endian). If it is 0, then the number is odd, if it is 1, then its even. Much more efficient than calling modulo which incorporates division.
Finally, main is type int and therefore returns a value.
Putting those pieces together, you can do something simple like the following:
#include <stdio.h>
#include <stdlib.h>
void EvenNumber (int *array, int *even, int size, int *esize);
int main (void)
{
int array[] = { 10,2,9,3,1,98,8 },
i, n = sizeof array / sizeof *array,
even[n], /* a VLA of the same size as array is fine here */
esize = 0;
EvenNumber (array, even, n, &esize);
printf ("array: ");
for (i = 0; i < n; i++)
printf (" %2d", array[i]);
printf ("\neven : ");
for (i = 0; i < esize; i++)
printf (" %2d", even[i]);
putchar ('\n');
return 0;
}
void EvenNumber (int *array, int *even, int size, int *esize)
{
int i;
for (i = 0; i < size; i++)
if ((array[i] & 1) == 0) /* simply looking at bit-0 is all you need */
even[(*esize)++] = array[i];
}
Note: esize is passed as a pointer to EvenNumber and updated within the function so that the number of elements in even are available back in the calling function (main() here).
Example Use/Output
$ ./bin/arrayeven
array: 10 2 9 3 1 98 8
even : 10 2 98 8
Let me know if you have any further questions.
I have the following solution for the knapsack problem:(wt[] is the weights array, val[] is the values array, n is the arrays size, index is the current item that we are trying (for the recursion) and arr is an array that represents weather or not item i was included in the solution.
int knapSack(int W, int wt[], int val[], int n, int index, int arr[])
{
if (n == index || W == 0)
return 0;
if (wt[index] > W)
return knapSack(W, wt, val, n, index+1 );
int with=val[index]+knapSack(W-wt[index], wt, val, n, index+1);
int without=knapSack(W, wt, val, n, index+1);
if(with>without){
arr[index]=1;
return with;
}
else{
arr[index]=0;
return without;
}
}
I am trying to print, in this recursive solution the items that are chosen, by setting the indexes of the taken ones in an array (res) to 1.
As I understand, if with>without, it means that I am choosing the current item, or item #index. So why is this not returning a right value?
I am using the recursive algorithm for a reason, I know using the memoization version can be easier here.
Example:
Weights: 5 6 7 10 11
Values: 2 4 5 6 9
W=25
Will return 5 ones in array res. When solution is 18 with items 2,3,5 (starting from index 1).
Premise 1: in your code, the recursion calls to knapSack are not passing arr, which should cause a compilation error, I assume it's just a copy/paste error.
Premise 2: with the data you proposed, the resulting arr value is not all 1 as you indicated, but 01011, which is still incorrect.
Consider the hypothetical situation in which, during the execution of your function, with is greater than without: during the with calculation arr is filled with the correct values; but then start the without calculation which is going to overwrite the arr values.
Since with is greater than without, the returned arr will be the wrong one, and this is the cause of the problem.
A simple fix would be to make a copy of the arr returned by the with calculation so it is not going to be overwritten by the without calculation, for example:
int with=val[index]+knapSack(W-wt[index], wt, val, n, index+1, arr);
// copy the "with" arr
int arrWith[n];
copyArr(arr, arrWith, n);
int without=knapSack(W, wt, val, n, index+1, arr);
if(with>without){
// restore the "with" arr
copyArr(arrWith, arr, n);
arr[index]=1;
return with;
}
else{
arr[index]=0;
return without;
}
copyArr is simply:
void copyArr(int arr[], int arrDest[], int n) {
int i;
for(i = 0; i < n; i++) {
arrDest[i] = arr[i];
}
}
With this fix the resulting value of arr is correctly 01101.
I tried to write a function that performs binary search. the code I wrote is as follows:
int binarySearch (int num[], int value, int left, int right)
{
if (left > right)
return -1;
else
{
int middle = (left+right)/2;
if (num[middle] = value)
return middle;
else
{
if (value < num[middle])
return binarySearch(num, value, left, middle-1);
else
return binarySearch(num, value, middle+1, right);
}
}
return 0;
}
void main()
{
int num[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int result;
result = binarySearch(num,6,0,15);
printf("The result is: %d", result);
}
While trying to debug it I found out the num[] array doesn't being send into the function. When I look at the array outside of the function it contains 16 numbers. when I jump into the function with F11 the array that arr[] receives contains only 0. Nothing I try seems to solve it. Does someone understands what goes wrong?
Thank you very much,
Robert
In binarySearch function num acts as pointer. So, when you debug, it shows only first value (0) pointed by num.
If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received.
int func(int arr[], ...){
.
.
.
}
int func(int arr[SIZE], ...){
.
.
.
}
int func(int* arr, ...){
.
.
.
}
However, by mistake you did an assignment instead of comparison, in if (arr[middle] = value).
Thanks !!!
Arrays cannot be sent as function arguments in C. Arguments declared as array are converted to pointers that point at the element of array, according to N1570 6.7.6.3.
Arrays used in expressions are automatically converted to pointers pointing the first element of the array except for some exceptions such as operands of unary & operator and sizeof operator, according to N1570 6.3.2.1.
Therefore, the acutual type of arr is int* and it seems that the debugger recognized only the elemente pointed at directly by the pointer.
There are a few syntax errors that are stopping your code from working. (e.g. while loop has a ";" ignoring the loop content).
The biggest issue with your code is that you calculated the middle index incorrectly.
Incorrect:
middle = (left + right) / 2;
Correct:
middle = ((right - left) / 2) + left;
You need to subtract to get the actual distance between left and right, then divide by 2 to get the middle. Then add back to the smaller value to reach the middle between the left and right sides.
Here is your code with syntax fixed and a mid function to make things easier. Enjoy.
int mid(int min, int max) {
return ((max - min) / 2) + min;
}
int binarySearch(int value, int arr[], int left, int right)
{
int middle = mid(left,right);
while (left < right)
{
if (arr[middle] == value)
return middle;
if (value < arr[middle])
middle = mid(left, middle);
else
middle = mid(middle, right);
}
return -1;
}
You should just use the int * syntax in your function signature. C will handle this by passing a pointer to the first element of the array. In C, arrays are not passed like they are in Java or other high-level languages.
Note that you can still use the [] operator on a pointer, similarly to an array. In your example, you can refer to the 2nd element of the array by using this syntax:
int x = num[1]; /* get the second element of the num array */
This would be the updated function (copied "as is" from the original), with only changes made specific to the array usage:
int binarySearch (int *num, int value, int left, int right)
{
if (left > right)
return -1;
else
{
int middle = (left+right)/2;
if (num[middle] = value)
return middle;
else
{
if (value < num[middle])
return binarySearch(num, value, left, middle-1);
else
return binarySearch(num, value, middle+1, right);
}
}
return 0;
}
void main()
{
int num[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int result;
result = binarySearch(num,6,0,15);
printf("The result is: %d", result);
}
One additional thing that you typically need to do is pass the length of the array as a separate argument. This is so that the function can know how many elements are in the array. C does not automatically pass the array length the pointer to the first array element, so you have to take care of it manually.
The OP's code does not use the length of the array, so length is not added to that function signature. However, requiring access to the length of a C array and passing it to a function is so common that it bears an clear example. Consider this example function to sum the values of an array:
int summation_function(int * array, size_t length)
{
int sum = 0;
size_t i = 0;
for (; i < length; ++i) {
sum += array[i];
}
return sum;
}
To call summation_function, you can do something like this:
int values[] = {1,2,4,8,16,32};
int sum = summation_function(values, sizeof(values)/sizeof(int));
printf("Summation of the values [1,2,4,8,16,32] is %d\n", sum);
Note the use of this code in this example:
sizeof(num)/sizeof(int)
What this does is find the allocated number of bytes in the array (the sizeof(num)) and divide by the number of bytes in an int (the sizeof(int)). The result is the exact number of elements in the array. With this, you can avoid hard-coding array lengths. This code is idiomatic of C array handling, so it becomes second nature to understand it after the first few uses.