give me a hand to understand this code - c

i have to write a c code that finds minimum of an array using recursion.i found this in the internet, but i don't understand it very well, can someone help me understand it?
#include <stdio.h>
int a[100],i;
void read(int i,int n)
{
if(i>=n)
return;
printf("element %d",i);
scanf("%d",&a[i]);
read(i+1,n);
}
int rec(int a[],int n)
{
int min;
if(n==1)
return a[0];
else {
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];
}
}
void main()
{
int i,j,n,a[100];
printf("enter n :");
scanf("%d",&n);
read(0,n);
printf("\n%d",rec(a,n));
getch();
}

if n=1, then min. is a[0] as there is only one element.
if n>1, then it is calling rec with the array and n-1 as the length each time. So, there will be a time when n=1 and returns a[0]. Then it will compare a[0] with a[1]. And return the minimum. Then it will compare the returned value minimum with a[2] and return the smaller value....and so on.

It calculates the minimal value in the array. Look at it that way:
Suppose you're given an array with 10 numbers. A magician tells you the the minimal value of that last 9 elements is 5. You now take the first element and compare it to 5. if it's smaller you return it, otherwise you return 5. The magician is the recursive call to the array with the last n-1 numbers.

rec(a, n) return the minimum value in {a[0], ..., a[n-1]}
Now we discuss two cases:
If n = 1, then rec(a,n) should be a[0], since there is only one value
Otherwise, rec(a,n) should be the minimum value of rec(a,n-1) (that is, the minimum value in {a[0],..,a[n-2]}) and a[n-1], which is what the following code do:
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];

int rec(int a[],int n)
{
int min;
if(n==1)
return a[0];
else {
min=rec(a,n-1);
if(min<a[n-1])
return min;
else
return a[n-1];
}
}
This function will go through all of your array elements, then compare them one by one, and each time return the smaller one, giving you the minimum of your array :
example : for a = {10,2,4,5}
rec will start from 5 and just calls itself with the previous elem until he's at the first : 10
then will return 10
will compare 10 with 2 and return 2 because 2 < 10
will compare 2 with 4 and return 2 because 2 < 4
will compare 2 with 5 and return 2 because 2 < 5

This program reads a size of an array the user wants to input, next it calls "read" which reads array elements of the given size recursively and fills in global array "a". Next it tries to find a minimal value of the local "a" array using recursive function "rec", that is initialized with garbage by the fact of being of "auto" variable type and types this value to the terminal screen. Next it waits for the user to type any character.

Related

Program to run function

I have a question for my assignment:
Write a function called second which takes, as parameters, an array of
positive integers and also an integer representing the size of the
array. The function returns the value of the second largest integer in
the array. If the largest integer in the array repeats, then the
second largest integer is also the largest. For example, if we have
{1, 2, 3, 4, 5, 5 }, the second largest integer is
5. The function should not change the contents of the array in any way. You can assume that the size of the array is at least two.
What I've done:
int second(const int arr[], int size)
{
int num1,num2;
int i;
if(arr[0]>arr[1])
{
num1=arr[0];num2=arr[1];
}
else
{
num1=arr[1];num2=arr[0];
}
for (i=2; i<size; i++)
{
if (arr[i]>num1)
{
num2=num1;
num1=arr[i];
}
else if (arr[i] > num2)
{
num2=arr[i];
}
}
return num2;
}
I have no idea how to type a program that can run the above function and display the integer '5'
The function should not change the contents of the array in any way.
Use a temporary array to perform all the operations. Simply copy the elements from the old array to the new temp array.
Write a function called second which takes, as parameters, an array of
positive integers and also an integer representing the size of the
array
Case 1: if the array is unsorted
You could just sort the elements(ascending order) and return the second last element.
Case 2: If the array is sorted
Just return the second last element.
There are lots of sorting algorithms like quicksort and mergesort which give you a better runtime but you could use bubble sort as well if there is no constraint on time complexity.
Additional Hint:
int second(const int arr[], int size)
{
int temp[size]; //<-----use a temporary array as you're not allowed to modify the original array
int i;
for(i=0;i<size;i++)
{
//copy the elements
}
//sort the temp array in ascending order
return temp[size-2]; //<----return the second last elements
}
I am not looking at your function second. I will leave that to you as an exercise.
To run this function, you will need to make a main program which will create this array and call this function.
#include <stdio.h>
int second(const int arr[], int size);
int main(void)
{
int arr[] = {1,2,3,4,6,7};
int N = sizeof(arr)/sizeof(arr[0]);
printf ("%d ", second(arr, N));
}
You can add your code below the code here and compile.

User- Defined Function Returns 0 even when it should not

Custom Input : 2 0 1 1 3 0 1 1 -1
Expected output : YES.
My Output : NO.
My Code :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int pv(int *a, int i){ //Function to create positional value.
if(a[i]!=0) return (a[i]+i);
else return 0;
}
int main() {
//code
int i,j,k,check=0;
int *a = (int *)malloc(1024*sizeof(int));
for(i=1;;i++) { scanf("%d",a+i);
if(*(a+i)==-1) { i--; break; } }
a = realloc(a,(i+1)*sizeof(int));//Just to decrease the size.
//Array of numbers inputed with designation from 1 formed.
int max_pv =0;
for(k=1;k<i;){
for(j=k+1;j<=pv(&a[k],k);){
if(max_pv<pv(&a[j],j)) {
max_pv = pv(&a[j],j);
check =j;//Location of max_pv.
}
}
k = check;
if(max_pv==0) { printf("NO"); return 0; }
if(max_pv>=i) { printf("YES"); return 0;}
max_pv = 0;
}
}
Problem Statement :
You will be given as input, a list of non-negative integers. The list will end with a -1 but the -1 is not a part of the list. The value of a number in this list denotes its "jump size".
For example, if the number at location i is 3, then the jump size at that element is 3. This means that all locations to the right of that location, within a distance of 3, are reachable from that location in a single jump. More precisely, in a single "jump" Mr C can go from location i to location i+1 or i+2 or i+3 if the number at location i is 3.
The first number of the list is said to be at location 1 (not like arrays where the first element is subscript 0). The number at location j will be said to be "reachable" from location i if it can be reached in any number of jump. Mr C starts by jumping on location 1 (this is his initial jump). He can now take any number of jumps, in any order, as allowed by the above rules. However, all jumps are made to the right of the list i.e. no backward jumps.
Print, as your output "YES" (without quotes) if the last location in the list (i.e. the location just before -1 is there) is reachable from location 1, else print "NO" (without quotes).
My problem :
I tried running the debugger on this code and the error I'm getting is that the function pv is returning zero even for k = 1.
In this example a[1] = 2. So the function should return a[1] + 2 = 3. But it's returning 0.
This is according to the debugger. If any other problem persists please mention them as well.
Thank you.
You are passing a pointer to a[j] (or a[k]) instead of just a to pv.

Array index of smallest number greater than a given number in a sorted array using C

Need to find the index of a number, that may or may not be present in the array. I tried the below code:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *lhs, const void *rhs){
return ( *(long long*)lhs - *(long long*)rhs );
}
int main(){
int size = 9;
long long a[] = {16426799,16850699,17802287,18007499,18690047,18870191,18870191,19142027,19783871};
long long x = 17802287;
long long *p = (long long *)bsearch(&x, a, size, sizeof(long long), cmp);
if (p != NULL)
printf("%lld\n", p - a);
return 0;
}
The above code works if the number, in this case 17802287 is present in the array a, but fails if the number is not present in a, e.g. doesn't give any output for x=18802288, I would like to get the index i=5 in that case 5th element onwards the elements are greater than 18802288.
Also the actual array size will have number of elements more than 4 million, would the same code work?
Thanks for the help.
From the man page for bsearch:
The bsearch() function returns a pointer to a matching member of
the array, or NULL if no match is found. If there are multiple
elements that match the key, the element returned is unspecified.
So the function will return NULL if the element in question is not found. If you want to find the first element greater than or equal to the number in question, you'll need to roll your own function to do that.
One of the possible solution can be:
int i, outcome = -1;
for( i = 0; i < size; i++ )
{
if( x == a[i] )
{
outcome = i;
break;
}
}
printf("%d\n", outcome);
You need to write a function that does approximately this:
bsearch_geq (number array low high)
if low is equal to high return high
let halfway be average of low and high
if array[halfway] is equal to number then return halfway
if array[halfway] is greater than number then
return result of "bsearch_geq number array low halfway"
else
return result of "bsearch_geq number array halfway high"
That'll get you 99% of the way, I think, but I'll leave it as an exercise to the reader to figure out the corner cases. The main one I can see is what happens when you get down to just two numbers because the naive "average" may cause infinite recursion.
If you can have multiple occurrences of the same number in the array then you'll need to drop the if array[halfway] is equal]" line.
You should ensure your solution uses tail-recursion for efficiency, but it's not too critical as 4m data-entries only amounts to about 15 recursive calls.

Array percentage algorithm implementation

So I just stared programming in C a few days ago and I have this program which takes an unsorted file full of integers, sorts it using quicksort
1st algorithm
Any suggestions on what I have done wrong in this?
From what you have described, it sounds like you are almost there. You are attempting to get the first element of a collection that has a value equal to (or just greather than) 90% of all the other members of the collection. You have already done the sort. The rest should be simply following these steps (if I have understood your question):
1) sort collection into an into array (you've already done this I think)
2) count numbers in collection, store in float n; //number of elements in collection
3) index through sorted array to the 0.9*n th element, (pick first one beyond that point not a duplicate of previous)
4) display results
Here is an implementation (sort of, I did not store n) of what I have described: (ignore the random number generator, et al., it is just a fast way to get an array)
#include <ansi_c.h>
#include <windows.h>
int randomGenerator(int min, int max);
int NotUsedRecently (int number);
int cmpfunc (const void * a, const void * b);
int main(void)
{
int array[1000];
int i;
for(i=0;i<1000;i++)
{
array[i]=randomGenerator(1, 1000);
Sleep(1);
}
//sort array
qsort(array, 1000, sizeof(int), cmpfunc);
//pick the first non repeat 90th percent and print
for(i=900;i<999;i++)
{
if(array[i+1] != array[i])
{
printf("this is the first number meeting criteria: %d", array[i+1]);
break;
}
}
getchar();
return 0;
}
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
srand(clock());
while(trying)
{
random = (rand()/32767.0)*(max+1);
(random >= min) ? (trying = 0) : (trying = 1);
}
return random;
}
And here is the output for my first randomly generated array (centering around the 90th percentile), compared against what the algorithm selected: Column on left is the element number, on the right is the sorted list of randomly generated integers. (notice it skips the repeats to ensure smallest value past 90%)
In summary: As I said, I think you are already, almost there. Notice how similar this section of my code is to yours:
You have something already, very similar. Just modify it to start looking at 90% index of the array (whatever that is), then just pick the first value that is not equal to the previous.
One issue in your code is that you need a break case for your second algorithm, once you find the output. Also, you cannot declare variables in your for loop, except under certain conditions. I'm not sure how you got it to compile.
According this part:
int output = array[(int)(floor(0.9*count)) + 1];
int x = (floor(0.9*count) + 1);
while (array[x] == array[x + 1])
{
x = x + 1;
}
printf(" %d ", output);
In while you do not check if x has exceeded count... (What if all the top 10% numbers are equal?)
You set output in first line and print it in last, but do not do antything with it in meantime. (So all those lines in between do nothing).
You definitely are on the right track.

Passing Array to a function and Adding it through Recursion

What em trying to do is pass the array to a function which will add all the array elements and return the output. Please help me. i dont know what i am doing wrong in this :/
#include <stdio.h>
#define MAX 5
int arraySum(int *dArr,int lim);
int main()
{
int array[MAX] = {9,7,4,2,10};
printf("%d", arraySum(array, MAX));
return 0;
}
int arraySum(int *dArr,int lim)
{
int Ans;
if(lim>0)
Ans = dArr[lim] + arraySum(*dArr, lim--);
return Ans;
}
There are several problems with your code:
You're accessing array[MAX], which is undefined behaviour.
Your function returns the uninitialized Ans when lim is zero.
The first argument to arraySum in the recursive call is wrong.
The use of lim-- is wrong.
Since this looks like homework, I'll let you figure out how to fix these problems. If this isn't homework, you might want to consider whether recursion is the right tool for the job.
You run into undefined behavior on dArr[lim], because lim is 5 and the array has elements 0...4.
You also get undefined behavior when lim==0, because you return an un-initialized Ans. When you declare it, initialize it to dArr[0].
After you fix this, you'll want to pass dArr itself further in the recursion, as dArr only returns an int.
Remember that computers treat 0 as the first number, so your array will number from element[0] to element[4]. your code starts from five and counts down to one, which means elements[5] in this case will return garbage, because the index does not exist. pass Lim - 1 into the function or manually changed the value in your function.
ArraySum(Array, MAX - 1);
OR
ArraySum(//....)
{
lim--;
//code here....
}
EDIT: you also need to initialize ans to some value, so if an array of zero elements is passed the function wont return an uninitialized variable.
int arraySum(int *dArr,int lim)
{
int Ans;
if(lim>=0) // note the change here
Ans = dArr[lim] + arraySum(dArr, --lim); // note the --lim change here
return Ans;
}
You should invoke this with lim as 4 and not 5. Because the array has 5 integers starting from index 0 to index 4. 5th index is out of bounds.
--lim instead of lim-- because lim-- is post decrement. That means the value is first passed and then decremented. Hence everytime your arraySum function gets the value as 4 instead of 3, 2, 1 and 0 (as per your expectation). --lim is pre-decrement.
Change MAX to 4 and change the if(lim>0) condition as if(lim>=0)
This will make your recursion to add as dArr[4]+dArr[3]+dArr[2]+dArr[1]+dArr[0] i.e. all 5 elements of the array.
EDIT: Corrected program:
int main()
{
int array[MAX] = {9,7,4,2,10};
printf("%d", arraySum(array, MAX-1));
return 0;
}
int Ans = 0;
int arraySum(int *dArr,int lim)
{
if(lim>=0){
Ans = dArr[lim] + arraySum(dArr, lim-1);
}
return Ans;
}

Resources